From 9a613a291536940e0276a42034e8db2bab03d1df Mon Sep 17 00:00:00 2001 From: alja Date: Thu, 9 Jun 2022 11:17:44 -0700 Subject: [PATCH 001/104] Handle selection for filtered digits. Enable custom tooltip --- graf3d/eve7/inc/ROOT/REveBoxSet.hxx | 1 + graf3d/eve7/inc/ROOT/REveDigitSet.hxx | 28 +++-- graf3d/eve7/src/REveBoxSet.cxx | 111 ++++++++------------ graf3d/eve7/src/REveDigitSet.cxx | 141 +++++++++++++++++++++++--- tutorials/eve7/boxset.C | 10 ++ tutorials/eve7/collection_proxies.C | 11 +- ui5/eve7/lib/EveElements.js | 27 +++-- 7 files changed, 225 insertions(+), 104 deletions(-) diff --git a/graf3d/eve7/inc/ROOT/REveBoxSet.hxx b/graf3d/eve7/inc/ROOT/REveBoxSet.hxx index c25c6b87d6571..9900831a9d62e 100644 --- a/graf3d/eve7/inc/ROOT/REveBoxSet.hxx +++ b/graf3d/eve7/inc/ROOT/REveBoxSet.hxx @@ -64,6 +64,7 @@ protected: Bool_t fDrawConeCap; static Int_t SizeofAtom(EBoxType_e bt); + void WriteShapeData(REveDigitSet::DigitBase_t &digit); public: REveBoxSet(const char* n="REveBoxSet", const char* t=""); diff --git a/graf3d/eve7/inc/ROOT/REveDigitSet.hxx b/graf3d/eve7/inc/ROOT/REveDigitSet.hxx index 900820fab9ba1..9a2ad97141d0a 100644 --- a/graf3d/eve7/inc/ROOT/REveDigitSet.hxx +++ b/graf3d/eve7/inc/ROOT/REveDigitSet.hxx @@ -42,8 +42,8 @@ class REveDigitSet : public REveElement, public: enum ERenderMode_e { kRM_AsIs, kRM_Line, kRM_Fill }; - typedef void (*Callback_foo)(REveDigitSet*, Int_t, TObject*); - typedef TString (*TooltipCB_foo)(REveDigitSet*, Int_t); + typedef void (*Callback_foo)(const REveDigitSet*, Int_t, TObject*); + typedef std::string (*TooltipCB_foo)(const REveDigitSet*, Int_t); struct DigitBase_t { @@ -56,12 +56,14 @@ public: }; protected: - std::vector fDigitIds; // Array holding references to external objects. + TRefArray *fDigitIds{nullptr}; // Array holding references to external objects. Int_t fDefaultValue; // Default signal value. Bool_t fValueIsColor; // Interpret signal value as RGBA color. Bool_t fSingleColor; // Use the same color for all digits. Bool_t fAntiFlick; // Make extra render pass to avoid flickering when quads are too small. + + Bool_t fOwnIds{false}; // Flag specifying if id-objects are owned by the TEveDigitSet. Bool_t fDetIdsAsSecondaryIndices; // Flag specifying if id-objects are owned by the REveDigitSet. REveChunkManager fPlex; // Container of digit data. DigitBase_t* fLastDigit; //! The last / current digit added to collection. @@ -97,10 +99,9 @@ public: /* virtual void UnSelected(); virtual void UnHighlighted(); - +*/ using REveElement::GetHighlightTooltip; - virtual TString GetHighlightTooltip(); - */ + std::string GetHighlightTooltip(const std::set& secondary_idcs) const override; // Implemented in sub-classes: // virtual void Reset(EQuadType_e quadType, Bool_t valIsCol, Int_t chunkSize); @@ -118,13 +119,14 @@ public: void DigitColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255); void DigitColor(UChar_t* rgba); - void DigitId(Int_t n); + void DigitId(TObject* id); + void DigitId(Int_t n, TObject* id); Bool_t GetDetIdsAsSecondaryIndices() const { return fDetIdsAsSecondaryIndices; } void SetDetIdsAsSecondaryIndices(Bool_t o) { fDetIdsAsSecondaryIndices = o; } DigitBase_t* GetDigit(Int_t n) const { return (DigitBase_t*) fPlex.Atom(n); } - Int_t GetId(Int_t n) const; + TObject* GetId(Int_t n) const; // -------------------------------- @@ -173,6 +175,16 @@ public: TooltipCB_foo GetTooltipCBFoo() const { return fTooltipCBFoo; } void SetTooltipCBFoo(TooltipCB_foo f) { fTooltipCBFoo = f; } + bool IsDigitVisible(const DigitBase_t*) const; + int GetAtomIdxFromShapeIdx(int) const; + int GetShapeIdxFromAtomIdx(int) const; + + void NewShapePicked(int shapeId, Int_t selectionId, bool multi); + + + bool RequiresExtraSelectionData() const override { return true; }; + void FillExtraSelectionData(nlohmann::json& j, const std::set& secondary_idcs) const override; + Int_t WriteCoreJson(nlohmann::json &j, Int_t rnr_offset) override; }; diff --git a/graf3d/eve7/src/REveBoxSet.cxx b/graf3d/eve7/src/REveBoxSet.cxx index c7543e6fe089d..fcf8ba93025f3 100644 --- a/graf3d/eve7/src/REveBoxSet.cxx +++ b/graf3d/eve7/src/REveBoxSet.cxx @@ -342,86 +342,61 @@ Int_t REveBoxSet::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset) } //////////////////////////////////////////////////////////////////////////////// -/// Crates 3D point array for rendering. +/// Creates 3D point array for rendering. void REveBoxSet::BuildRenderData() { - fRenderData = std::make_unique("makeBoxSet", fPlex.Size()*24, 0, fPlex.Size()); + fRenderData = std::make_unique("makeBoxSet", fPlex.Size() * 24, 0, fPlex.Size()); - switch (fBoxType) - { - case REveBoxSet::kBT_FreeBox: - { - REveChunkManager::iterator bi(fPlex); - while (bi.next()) - { - REveBoxSet::BFreeBox_t& b = * (REveBoxSet::BFreeBox_t*) bi(); - // vertices - for (int c =0; c < 8; c++) { - for (int j =0; j < 3; j++) - fRenderData->PushV(b.fVertices[c][j]); + REveChunkManager::iterator bi(fPlex); + while (bi.next()) { + REveDigitSet::DigitBase_t *b = (REveDigitSet::DigitBase_t *)bi(); + if (IsDigitVisible(b)) { + WriteShapeData(*b); + if (fSingleColor == false) { + + if (fValueIsColor) { + fRenderData->PushI(int(b->fValue)); + } else if (fSingleColor == false) { + UChar_t c[4] = {0, 0, 0, 0}; + fPalette->ColorFromValue(b->fValue, fDefaultValue, c); + + int value = c[0] + c[1] * 256 + c[2] * 256 * 256; + + // printf("box val [%d] values (%d, %d, %d) -> int <%d>\n", b.fValue, c[0], c[1], c[2], value); + fRenderData->PushI(value); } } - break; - } - case REveBoxSet::kBT_AABox: - { - REveChunkManager::iterator bi(fPlex); - while (bi.next()) - { - REveBoxSet::BAABox_t& b = * (REveBoxSet::BAABox_t*) bi(); - // position - fRenderData->PushV(b.fA, b.fB, b.fC); - // dimensions - fRenderData->PushV(b.fW, b.fH, b.fD); - } - break; } - default: - assert(false && "REveBoxSet::BuildRenderData only kBT_FreeBox type supported"); } +} - // - // setup colors - // - if (fSingleColor == false) - { - REveChunkManager::iterator bi(fPlex); - while (bi.next()) - { - REveDigitSet::DigitBase_t& b = * (REveDigitSet::DigitBase_t*) bi(); - if (fValueIsColor) - { - fRenderData->PushI(int(b.fValue)); - } - else if (fSingleColor == false) - { - UChar_t c[4] = {0, 0, 0, 0}; - Bool_t visible = fPalette->ColorFromValue(b.fValue, fDefaultValue, c); - - int value = - c[0] + - c[1] * 256 + - c[2] * 256*256; - - // printf("box val [%d] values (%d, %d, %d) -> int <%d>\n", b.fValue, c[0], c[1], c[2], value); - - // presume transparency 100% when non-visible - if (!visible) - value += 256*256*256*c[3]; - - - fRenderData->PushI(value); - } +//////////////////////////////////////////////////////////////////////////////// +/// Write shape data for different cases +/// +void REveBoxSet::WriteShapeData(REveDigitSet::DigitBase_t &digit) +{ + switch (fBoxType) { + case REveBoxSet::kBT_FreeBox: { + REveBoxSet::BFreeBox_t &b = (REveBoxSet::BFreeBox_t &)(digit); + // vertices + for (int c = 0; c < 8; c++) { + for (int j = 0; j < 3; j++) + fRenderData->PushV(b.fVertices[c][j]); } + break; } - if (!fDigitIds.empty()) - { - for (int i = 0; i < fPlex.N(); ++i) - { - fRenderData->PushI(GetId(i)); - } + case REveBoxSet::kBT_AABox: { + REveBoxSet::BAABox_t &b = (REveBoxSet::BAABox_t &)(digit); + // position + fRenderData->PushV(b.fA, b.fB, b.fC); + // dimensions + fRenderData->PushV(b.fW, b.fH, b.fD); + + break; + } + default: assert(false && "REveBoxSet::BuildRenderData only kBT_FreeBox type supported"); } } diff --git a/graf3d/eve7/src/REveDigitSet.cxx b/graf3d/eve7/src/REveDigitSet.cxx index 13be753f2ffa2..2fe7e206dcd4e 100644 --- a/graf3d/eve7/src/REveDigitSet.cxx +++ b/graf3d/eve7/src/REveDigitSet.cxx @@ -12,6 +12,7 @@ #include "ROOT/REveDigitSet.hxx" #include "ROOT/REveManager.hxx" #include "ROOT/REveTrans.hxx" +#include "ROOT/REveSelection.hxx" #include "TRefArray.h" @@ -142,7 +143,15 @@ REveDigitSet::DigitBase_t* REveDigitSet::NewDigit() void REveDigitSet::ReleaseIds() { - fDigitIds.clear(); + if (fDigitIds) + { + const Int_t N = fDigitIds->GetSize(); + + for (Int_t i = 0; i < N; ++i) + delete fDigitIds->At(i); + + fDigitIds->Expand(0); + } } //////////////////////////////////////////////////////////////////////////////// @@ -191,34 +200,32 @@ void REveDigitSet::UnHighlighted() REveElement::UnHighlighted(); } +*/ //////////////////////////////////////////////////////////////////////////////// /// Return tooltip for highlighted element if always-sec-select is set. /// Otherwise return the tooltip for this element. -TString REveDigitSet::GetHighlightTooltip() +std::string REveDigitSet::GetHighlightTooltip(const std::set& secondary_idcs) const { - if (fHighlightedSet.empty()) return ""; - if (GetAlwaysSecSelect()) { if (fTooltipCBFoo) { - return (fTooltipCBFoo)(this, *fHighlightedSet.begin()); + return (fTooltipCBFoo)(this, *secondary_idcs.begin()); } else if (fDigitIds) { - TObject *o = GetId(*fHighlightedSet.begin()); + TObject *o = GetId(*secondary_idcs.begin()); if (o) - return TString(o->GetName()); + return o->GetName(); } - return TString::Format("%s; idx=%d", GetElementName(), *fHighlightedSet.begin()); + return TString::Format("%s; idx=%d", GetCName(), *secondary_idcs.begin()).Data(); } else { - return REveElement::GetHighlightTooltip(); + return REveElement::GetHighlightTooltip(secondary_idcs); } } -*/ //////////////////////////////////////////////////////////////////////////////// /// Instruct underlying memory allocator to regroup itself into a /// contiguous memory chunk. @@ -311,21 +318,34 @@ void REveDigitSet::DigitColor(UChar_t* rgba) x[0] = rgba[0]; x[1] = rgba[1]; x[2] = rgba[2]; x[3] = rgba[3]; } +//////////////////////////////////////////////////////////////////////////////// +/// Set external object reference for the last digit added. + +void REveDigitSet::DigitId(TObject* id) +{ + DigitId(fLastIdx, id); +} //////////////////////////////////////////////////////////////////////////////// /// Set external id for the last added digit. -void REveDigitSet::DigitId(Int_t n) +void REveDigitSet::DigitId(Int_t n, TObject* id) { - fDigitIds.push_back(n); + if (!fDigitIds) + fDigitIds = new TRefArray; + + if (fOwnIds && n < fDigitIds->GetSize() && fDigitIds->At(n)) + delete fDigitIds->At(n); + + fDigitIds->AddAtAndExpand(id, n); } //////////////////////////////////////////////////////////////////////////////// /// Set external object reference for digit n. -Int_t REveDigitSet::GetId(Int_t n) const +TObject* REveDigitSet::GetId(Int_t n) const { - return fDigitIds[n]; + return fDigitIds ? fDigitIds->At(n) : 0; } /* @@ -421,6 +441,99 @@ REveRGBAPalette* REveDigitSet::AssertPalette() return fPalette; } +//////////////////////////////////////////////////////////////////////////////// +/// Utility function for maping digit idx with visible shape idx +bool REveDigitSet::IsDigitVisible(const DigitBase_t *d) const +{ + if (fSingleColor) { + return true; + } else if (fValueIsColor) { + return d->fValue ? true : false; + } else { + if (fPalette) + return d->fValue > fPalette->GetMinVal() && d->fValue < fPalette->GetMaxVal(); + else { + printf("Error REveDigitSet::IsDigitVisible() unhadled case\n"); + return true; + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// Utility function for maping digit idx with visible shape idx +int REveDigitSet::GetAtomIdxFromShapeIdx(int iShapeIdx) const +{ + int atomIdx = 0; + int shapeIdx = 0; + for (Int_t c = 0; c < fPlex.VecSize(); ++c) { + Char_t *a = fPlex.Chunk(c); + Int_t n = fPlex.NAtoms(c); + while (n--) { + if (IsDigitVisible((DigitBase_t *)a)) { + if (shapeIdx == iShapeIdx) + return atomIdx; + shapeIdx++; + } + atomIdx++; + a += fPlex.S(); + } + } + + printf("REveDigitSet::GetAtomIdxFromShapeIdx Error locating atom idx from shape idx %d\n", iShapeIdx); + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +/// Utility function for maping shape idx to digit idx +int REveDigitSet::GetShapeIdxFromAtomIdx(int iAtomIdx) const +{ + int atomIdx = 0; + int shapeIdx = 0; + for (Int_t c = 0; c < fPlex.VecSize(); ++c) { + Char_t *a = fPlex.Chunk(c); + Int_t n = fPlex.NAtoms(c); + while (n--) { + if (IsDigitVisible((DigitBase_t *)a)) { + if (atomIdx == iAtomIdx) { + return shapeIdx; + } + shapeIdx++; + } + atomIdx++; + a += fPlex.S(); + } + } + + printf("REveDigitSet::GetShapeIdxFromAtomIdx:: Atom with idx %d dose not have a visible shape \n", iAtomIdx); + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +// Direct callback from EveElemenControl, function elementSelected/elementHighligted controll +// +void REveDigitSet::NewShapePicked(int shapeIdx, Int_t selectionId, bool multi) +{ + int digitId = GetAtomIdxFromShapeIdx(shapeIdx); + auto digit = GetDigit(digitId); + if (gDebug) printf("REveDigitSet::NewShapePicked shape ID = %d, atom ID = %d, value = %d\n", shapeIdx, digitId, digit->fValue); + + REveSelection *selection = dynamic_cast(ROOT::Experimental::gEve->FindElementById(selectionId)); + std::set sset = {digitId}; + + selection->NewElementPicked(GetElementId(), multi, true, sset); +} + +//////////////////////////////////////////////////////////////////////////////// +// called from REveSelection to stream specific selection data +void REveDigitSet::FillExtraSelectionData(nlohmann::json &j, const std::set &secondary_idcs) const +{ + j["shape_idcs"] = nlohmann::json::array(); + for (auto &i : secondary_idcs) { + j["shape_idcs"].push_back(GetShapeIdxFromAtomIdx(i)); + } +} + //////////////////////////////////////////////////////////////////////////////// /// Fill core part of JSON representation. diff --git a/tutorials/eve7/boxset.C b/tutorials/eve7/boxset.C index 1b2ea5baeeb07..2b98988e10d91 100644 --- a/tutorials/eve7/boxset.C +++ b/tutorials/eve7/boxset.C @@ -16,6 +16,12 @@ using namespace ROOT::Experimental; +std::string customTooltip(const ROOT::Experimental::REveDigitSet *digitSet, int n) +{ + auto d = digitSet->GetDigit(n); + return TString::Format("Custom tooltip:\n value %d idx %d\n", d->fValue, n).Data(); +} + REveBoxSet* boxset(Int_t num=100) { auto eveMng = REveManager::Create(); @@ -23,6 +29,8 @@ REveBoxSet* boxset(Int_t num=100) TRandom r(0); auto pal = new REveRGBAPalette(0, 130); + pal->SetMin(80); + auto q = new REveBoxSet("BoxSet"); q->SetPalette(pal); @@ -57,6 +65,8 @@ REveBoxSet* boxset(Int_t num=100) q->SetPickable(1); q->SetAlwaysSecSelect(1); + q->SetTooltipCBFoo(customTooltip); + eveMng->GetEventScene()->AddElement(q); eveMng->Show(); diff --git a/tutorials/eve7/collection_proxies.C b/tutorials/eve7/collection_proxies.C index faa0602596da6..4c0903a2f2b06 100644 --- a/tutorials/eve7/collection_proxies.C +++ b/tutorials/eve7/collection_proxies.C @@ -395,6 +395,7 @@ private: void buildBoxSet(REveBoxSet* boxset) { auto collection = Collection(); boxset->SetMainColor(collection->GetMainColor()); + boxset->SetPickable(true); boxset->Reset(REveBoxSet::kBT_FreeBox, true, collection->GetNItems()); TRandom r(0); #define RND_BOX(x) (Float_t)r.Uniform(-(x), (x)) @@ -839,13 +840,13 @@ void collection_proxies(bool proj=true) // create event data from list auto collectionMng = new CollectionManager(event); - +/* REveDataCollection* trackCollection = new REveDataCollection("Tracks"); trackCollection->SetItemClass(TParticle::Class()); trackCollection->SetMainColor(kGreen); trackCollection->SetFilterExpr("i.Pt() > 4.1 && std::abs(i.Eta()) < 1"); collectionMng->addCollection(trackCollection, new TParticleProxyBuilder(), true); - +*/ REveDataCollection* jetCollection = new REveDataCollection("Jets"); jetCollection->SetItemClass(Jet::Class()); jetCollection->SetMainColor(kYellow); @@ -856,8 +857,8 @@ void collection_proxies(bool proj=true) hitCollection->SetItemClass(RecHit::Class()); hitCollection->SetMainColor(kOrange + 7); hitCollection->SetFilterExpr("i.fPt > 5"); - collectionMng->addCollection(hitCollection, new RecHitProxyBuilder()); - + collectionMng->addCollection(hitCollection, new RecHitProxyBuilder(), true); +/* // add calorimeters auto calo3d = new REveCalo3D(event->fCaloData); calo3d->SetBarrelRadius(kR_max); @@ -875,7 +876,7 @@ void collection_proxies(bool proj=true) hcalCollection->SetItemClass(RCaloTower::Class()); hcalCollection->SetMainColor(kBlue); collectionMng->addCollection(hcalCollection, new CaloTowerProxyBuilder(event->fCaloData)); - +*/ // event navigation auto eventMng = new EventManager(event, collectionMng); eventMng->SetName("EventManager"); diff --git a/ui5/eve7/lib/EveElements.js b/ui5/eve7/lib/EveElements.js index 56c0b4e701393..3cbf4b2dcf04a 100644 --- a/ui5/eve7/lib/EveElements.js +++ b/ui5/eve7/lib/EveElements.js @@ -64,8 +64,9 @@ sap.ui.define(['rootui5/eve7/lib/EveManager'], function(/*EveManager*/) { class BoxSetControl extends EveElemControl { - DrawForSelection(sec_idcs, res) + DrawForSelection(atom_idcs, res, extra) { + let sec_idcs = extra.shape_idcs; let geobox = new THREE.BufferGeometry(); geobox.setAttribute( 'position', this.obj3d.geometry.getAttribute("position") ); @@ -113,19 +114,27 @@ sap.ui.define(['rootui5/eve7/lib/EveManager'], function(/*EveManager*/) { return t + " idx=" + idx; } - elementSelected(indx) + elementSelectedSendMIR(idx, selectionId) { - if (this.obj3d.eve_el.fDetIdsAsSecondaryIndices) { - let N = this.obj3d.eve_el.render_data.idxBuff.length / 2; - indx = this.obj3d.eve_el.render_data.idxBuff[N + indx]; - } + let boxset = this.obj3d.eve_el; + let scene = this.obj3d.scene; + let multi = this.event?.ctrlKey ? true : false; - this.invokeSceneMethod("processElementSelected", indx); + let boxIdx = idx; + + let fcall = "NewShapePicked(" + boxIdx + ", " + selectionId + ", " + multi + ")" + scene.mgr.SendMIR(fcall, boxset.fElementId, "ROOT::Experimental::REveDigitSet"); + return true; } - elementHighlighted(indx) + elementSelected(idx) { - this.invokeSceneMethod("processElementHighlighted", indx); + return this.elementSelectedSendMIR(idx, this.obj3d.scene.mgr.global_selection_id); + } + + elementHighlighted(idx) + { + return this.elementSelectedSendMIR(idx, this.obj3d.scene.mgr.global_highlight_id); } checkHighlightIndex(indx) From 7b524be35d28b9e402c3ccaf1956fe17f8054661 Mon Sep 17 00:00:00 2001 From: alja Date: Fri, 10 Jun 2022 15:06:05 -0700 Subject: [PATCH 002/104] Add check if digit is visible in FillExtraSelectionData --- graf3d/eve7/src/REveDigitSet.cxx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/graf3d/eve7/src/REveDigitSet.cxx b/graf3d/eve7/src/REveDigitSet.cxx index 2fe7e206dcd4e..59d2e3df39802 100644 --- a/graf3d/eve7/src/REveDigitSet.cxx +++ b/graf3d/eve7/src/REveDigitSet.cxx @@ -480,7 +480,7 @@ int REveDigitSet::GetAtomIdxFromShapeIdx(int iShapeIdx) const } printf("REveDigitSet::GetAtomIdxFromShapeIdx Error locating atom idx from shape idx %d\n", iShapeIdx); - return 0; + return -1; } //////////////////////////////////////////////////////////////////////////////// @@ -505,7 +505,7 @@ int REveDigitSet::GetShapeIdxFromAtomIdx(int iAtomIdx) const } printf("REveDigitSet::GetShapeIdxFromAtomIdx:: Atom with idx %d dose not have a visible shape \n", iAtomIdx); - return 0; + return -1; } @@ -516,11 +516,12 @@ void REveDigitSet::NewShapePicked(int shapeIdx, Int_t selectionId, bool multi) { int digitId = GetAtomIdxFromShapeIdx(shapeIdx); auto digit = GetDigit(digitId); - if (gDebug) printf("REveDigitSet::NewShapePicked shape ID = %d, atom ID = %d, value = %d\n", shapeIdx, digitId, digit->fValue); + if (gDebug) printf("REveDigitSet::NewShapePicked elementId %d shape ID = %d, atom ID = %d, value = %d\n", GetElementId(), shapeIdx, digitId, digit->fValue); REveSelection *selection = dynamic_cast(ROOT::Experimental::gEve->FindElementById(selectionId)); std::set sset = {digitId}; + RefSelectedSet() = sset; selection->NewElementPicked(GetElementId(), multi, true, sset); } @@ -530,7 +531,9 @@ void REveDigitSet::FillExtraSelectionData(nlohmann::json &j, const std::set { j["shape_idcs"] = nlohmann::json::array(); for (auto &i : secondary_idcs) { - j["shape_idcs"].push_back(GetShapeIdxFromAtomIdx(i)); + int shapeIdx = GetShapeIdxFromAtomIdx(i); + if (shapeIdx >= 0) + j["shape_idcs"].push_back(GetShapeIdxFromAtomIdx(i)); } } From 9ccf06008e27bb2c158d284415c97e7e0e537c74 Mon Sep 17 00:00:00 2001 From: alja Date: Fri, 10 Jun 2022 15:09:42 -0700 Subject: [PATCH 003/104] Add example for RecHit proxy buiders --- tutorials/eve7/collection_proxies.C | 96 ++++++++++++++++++----------- 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/tutorials/eve7/collection_proxies.C b/tutorials/eve7/collection_proxies.C index 4c0903a2f2b06..096790daf9b67 100644 --- a/tutorials/eve7/collection_proxies.C +++ b/tutorials/eve7/collection_proxies.C @@ -389,42 +389,59 @@ class TParticleProxyBuilder : public REveDataSimpleProxyBuilderTemplate(fSelectionMaster); + il->RefSelectedSet() = RefSelectedSet(); + return il; + } + return nullptr; + } + }; + + REveBoxSet *fBoxSet{nullptr}; + void buildBoxSet(REveBoxSet *boxset) + { auto collection = Collection(); boxset->SetMainColor(collection->GetMainColor()); + boxset->SetName(collection->GetCName()); boxset->SetPickable(true); + boxset->SetAlwaysSecSelect(1); + boxset->SetDetIdsAsSecondaryIndices(true); + boxset->SetSelectionMaster(((REveDataCollection *)collection)->GetItemList()); boxset->Reset(REveBoxSet::kBT_FreeBox, true, collection->GetNItems()); TRandom r(0); -#define RND_BOX(x) (Float_t)r.Uniform(-(x), (x)) - for (int h = 0; h < collection->GetNItems(); ++h) - { - RecHit* hit = (RecHit*)collection->GetDataPtr(h); - const REveDataItem* item = Collection()->GetDataItem(h); - if (!item->GetVisible()) - continue; +#define RND_BOX(x) (Float_t) r.Uniform(-(x), (x)) + for (int h = 0; h < collection->GetNItems(); ++h) { + RecHit *hit = (RecHit *)collection->GetDataPtr(h); + const REveDataItem *item = Collection()->GetDataItem(h); + Float_t x = hit->fX; Float_t y = hit->fY; Float_t z = hit->fZ; Float_t a = hit->fPt; Float_t d = 0.05; - Float_t verts[24] = { - x - a + RND_BOX(d), y - a + RND_BOX(d), z - a + RND_BOX(d), - x - a + RND_BOX(d), y + a + RND_BOX(d), z - a + RND_BOX(d), - x + a + RND_BOX(d), y + a + RND_BOX(d), z - a + RND_BOX(d), - x + a + RND_BOX(d), y - a + RND_BOX(d), z - a + RND_BOX(d), - x - a + RND_BOX(d), y - a + RND_BOX(d), z + a + RND_BOX(d), - x - a + RND_BOX(d), y + a + RND_BOX(d), z + a + RND_BOX(d), - x + a + RND_BOX(d), y + a + RND_BOX(d), z + a + RND_BOX(d), - x + a + RND_BOX(d), y - a + RND_BOX(d), z + a + RND_BOX(d) }; + Float_t verts[24] = {x - a + RND_BOX(d), y - a + RND_BOX(d), z - a + RND_BOX(d), x - a + RND_BOX(d), + y + a + RND_BOX(d), z - a + RND_BOX(d), x + a + RND_BOX(d), y + a + RND_BOX(d), + z - a + RND_BOX(d), x + a + RND_BOX(d), y - a + RND_BOX(d), z - a + RND_BOX(d), + x - a + RND_BOX(d), y - a + RND_BOX(d), z + a + RND_BOX(d), x - a + RND_BOX(d), + y + a + RND_BOX(d), z + a + RND_BOX(d), x + a + RND_BOX(d), y + a + RND_BOX(d), + z + a + RND_BOX(d), x + a + RND_BOX(d), y - a + RND_BOX(d), z + a + RND_BOX(d)}; boxset->AddBox(verts); - boxset->DigitId(h); - boxset->DigitColor(item->GetVisible() ? collection->GetMainColor() : 0); // set color on the last one + + boxset->DigitValue(item->GetVisible() ? 1 : 0); + if (item->GetVisible()) + boxset->DigitColor(item->GetMainColor()); } - boxset->GetPlex()->Refit(); + boxset->RefitPlex(); boxset->StampObjProps(); } @@ -432,33 +449,37 @@ public: using REveDataProxyBuilderBase::Build; void BuildProduct(const REveDataCollection* collection, REveElement* product, const REveViewContext*)override { - // printf("-------------------------FBOXSET proxy builder %d \n", collection->GetNItems()); - auto boxset = new REveBoxSet(); - boxset->SetName(collection->GetCName()); - boxset->SetAlwaysSecSelect(1); - boxset->SetDetIdsAsSecondaryIndices(true); - boxset->SetSelectionMaster(((REveDataCollection*)collection)->GetItemList()); - buildBoxSet(boxset); - product->AddElement(boxset); + fBoxSet = new FWBoxSet(); + buildBoxSet(fBoxSet); + product->AddElement(fBoxSet); } using REveDataProxyBuilderBase::FillImpliedSelected; void FillImpliedSelected(REveElement::Set_t& impSet, const std::set& sec_idcs, Product* p) override { - // printf("RecHit fill implioed ----------------- !!!%zu\n", Collection()->GetItemList()->RefSelectedSet().size()); - impSet.insert(p->m_elements->FirstChild()); + // printf("RecHit fill implioed ----------------- !!!%zu\n", Collection()->GetItemList()->RefSelectedSet().size()); + impSet.insert(fBoxSet); } using REveDataProxyBuilderBase::ModelChanges; void ModelChanges(const REveDataCollection::Ids_t& ids, Product* product) override { - // We know there is only one element in this product - // printf("RecHitProxyBuilder::model changes %zu\n", ids.size()); - buildBoxSet((REveBoxSet*)product->m_elements->FirstChild()); + for (auto &i : ids) + { + auto digi = fBoxSet->GetDigit(i); + auto item = Collection()->GetDataItem(i); + fBoxSet->SetCurrentDigit(i); + if (item->GetVisible()) { + fBoxSet->DigitValue(1); + fBoxSet->DigitColor(item->GetMainColor()); + } else { + fBoxSet->DigitValue(0); + } + } + fBoxSet->StampObjProps(); } }; // RecHitProxyBuilder - class CaloTowerProxyBuilder: public REveDataProxyBuilderBase { private: @@ -790,9 +811,10 @@ public: const std::set &secondary_idcs) { if (el) { + printf("DEVIATE %s \n", el->GetCName()); auto *colItems = dynamic_cast(el); if (colItems) { - // std::cout << "Deviate RefSelected=" << colItems->RefSelectedSet().size() << " passed set " << secondary_idcs.size() << "\n"; + std::cout << "Deviate RefSelected=" << colItems->RefSelectedSet().size() << " passed set " << secondary_idcs.size() << "\n"; ExecuteNewElementPicked(selection, colItems, multi, true, colItems->RefSelectedSet()); return true; } From c8e617ebbffb6f0ad3eda45fb7f8863544f8a5d1 Mon Sep 17 00:00:00 2001 From: alja Date: Fri, 10 Jun 2022 15:32:36 -0700 Subject: [PATCH 004/104] Remove debug prints --- tutorials/eve7/collection_proxies.C | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tutorials/eve7/collection_proxies.C b/tutorials/eve7/collection_proxies.C index 096790daf9b67..f1eb3cd43674c 100644 --- a/tutorials/eve7/collection_proxies.C +++ b/tutorials/eve7/collection_proxies.C @@ -811,10 +811,9 @@ public: const std::set &secondary_idcs) { if (el) { - printf("DEVIATE %s \n", el->GetCName()); auto *colItems = dynamic_cast(el); if (colItems) { - std::cout << "Deviate RefSelected=" << colItems->RefSelectedSet().size() << " passed set " << secondary_idcs.size() << "\n"; + // std::cout << "Deviate RefSelected=" << colItems->RefSelectedSet().size() << " passed set " << secondary_idcs.size() << "\n"; ExecuteNewElementPicked(selection, colItems, multi, true, colItems->RefSelectedSet()); return true; } From 5547dec9ece0b8733df85cea35b3743d5b05480b Mon Sep 17 00:00:00 2001 From: alja Date: Thu, 23 Jun 2022 11:15:57 -0700 Subject: [PATCH 005/104] Add check for empty boxset in makeBoxSet() --- ui5/eve7/lib/EveElements.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui5/eve7/lib/EveElements.js b/ui5/eve7/lib/EveElements.js index 3cbf4b2dcf04a..b14bdeb58e8e9 100644 --- a/ui5/eve7/lib/EveElements.js +++ b/ui5/eve7/lib/EveElements.js @@ -906,6 +906,9 @@ sap.ui.define(['rootui5/eve7/lib/EveManager'], function(/*EveManager*/) { makeBoxSet(boxset, rnr_data) { + if (!rnr_data.vtxBuff) + return new THREE.Mesh(); + let vBuff; if (boxset.boxType == 1) // free box { From 11c49f2ed4ba257ca8fdcc4776bd6cda5e908b39 Mon Sep 17 00:00:00 2001 From: alja Date: Thu, 23 Jun 2022 11:38:27 -0700 Subject: [PATCH 006/104] Changes comments --- tutorials/eve7/collection_proxies.C | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tutorials/eve7/collection_proxies.C b/tutorials/eve7/collection_proxies.C index f1eb3cd43674c..15105623250f2 100644 --- a/tutorials/eve7/collection_proxies.C +++ b/tutorials/eve7/collection_proxies.C @@ -861,13 +861,13 @@ void collection_proxies(bool proj=true) // create event data from list auto collectionMng = new CollectionManager(event); -/* + REveDataCollection* trackCollection = new REveDataCollection("Tracks"); trackCollection->SetItemClass(TParticle::Class()); trackCollection->SetMainColor(kGreen); trackCollection->SetFilterExpr("i.Pt() > 4.1 && std::abs(i.Eta()) < 1"); collectionMng->addCollection(trackCollection, new TParticleProxyBuilder(), true); -*/ + REveDataCollection* jetCollection = new REveDataCollection("Jets"); jetCollection->SetItemClass(Jet::Class()); jetCollection->SetMainColor(kYellow); @@ -879,7 +879,7 @@ void collection_proxies(bool proj=true) hitCollection->SetMainColor(kOrange + 7); hitCollection->SetFilterExpr("i.fPt > 5"); collectionMng->addCollection(hitCollection, new RecHitProxyBuilder(), true); -/* + // add calorimeters auto calo3d = new REveCalo3D(event->fCaloData); calo3d->SetBarrelRadius(kR_max); @@ -897,7 +897,7 @@ void collection_proxies(bool proj=true) hcalCollection->SetItemClass(RCaloTower::Class()); hcalCollection->SetMainColor(kBlue); collectionMng->addCollection(hcalCollection, new CaloTowerProxyBuilder(event->fCaloData)); -*/ + // event navigation auto eventMng = new EventManager(event, collectionMng); eventMng->SetName("EventManager"); From b386d38a3be00a78ae4e82919a1c1563b02116f4 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 23 Jun 2022 13:34:21 +0200 Subject: [PATCH 007/104] [asimage] use unique_ptr for TBox created in ProcessEvent Such pointer will be automatically released when unloading library or program is stopped --- graf2d/asimage/src/TASImage.cxx | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index 3cd9fd279ed50..67ba095f5586a 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -57,9 +57,10 @@ Several examples showing how to use this class are available in the ROOT tutorials: `$ROOTSYS/tutorials/image/` */ -# include -# include FT_FREETYPE_H -# include FT_GLYPH_H +#include +#include FT_FREETYPE_H +#include FT_GLYPH_H + #include "TASImage.h" #include "TASImagePlugin.h" #include "TROOT.h" @@ -89,6 +90,8 @@ ROOT tutorials: `$ROOTSYS/tutorials/image/` #include "TVirtualPadPainter.h" #include "snprintf.h" +#include + #ifndef WIN32 #ifndef R__HAS_COCOA # include @@ -1703,7 +1706,7 @@ Int_t TASImage::DistancetoPrimitive(Int_t px, Int_t py) void TASImage::ExecuteEvent(Int_t event, Int_t px, Int_t py) { - static TBox *ZoomBox; + static std::unique_ptr ZoomBox; if (!gPad) return; @@ -1762,9 +1765,8 @@ void TASImage::ExecuteEvent(Int_t event, Int_t px, Int_t py) ZoomBox->SetY1(gPad->AbsPixeltoY(pyl)); ZoomBox->SetX2(gPad->AbsPixeltoX(pxt)); ZoomBox->SetY2(gPad->AbsPixeltoY(pyt)); - } - else { - ZoomBox = new TBox(pxl, pyl, pxt, pyt); + } else { + ZoomBox = std::make_unique(pxl, pyl, pxt, pyt); ZoomBox->SetFillStyle(0); ZoomBox->Draw("l*"); } @@ -1800,10 +1802,9 @@ void TASImage::ExecuteEvent(Int_t event, Int_t px, Int_t py) Zoom((imgX1 < imgX2) ? imgX1 : imgX2, (imgY1 < imgY2) ? imgY1 : imgY2, TMath::Abs(imgX1 - imgX2) + 1, TMath::Abs(imgY1 - imgY2) + 1); - if (ZoomBox) { - ZoomBox->Delete(); - ZoomBox = 0; - } + if (ZoomBox) + ZoomBox.reset(); + gPad->Modified(kTRUE); gPad->Update(); break; From 0250f55e1d413447955e77cc705d8fc6a00c1817 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 23 Jun 2022 13:49:37 +0200 Subject: [PATCH 008/104] use std::vector to keep temporary array in TPolyLine::ExecuteEvent --- graf2d/graf/src/TPolyLine.cxx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/graf2d/graf/src/TPolyLine.cxx b/graf2d/graf/src/TPolyLine.cxx index 165b014c18f27..fc53a99a63b3c 100644 --- a/graf2d/graf/src/TPolyLine.cxx +++ b/graf2d/graf/src/TPolyLine.cxx @@ -10,6 +10,7 @@ *************************************************************************/ #include +#include #include "TROOT.h" #include "TBuffer.h" #include "TMath.h" @@ -267,7 +268,7 @@ void TPolyLine::ExecuteEvent(Int_t event, Int_t px, Int_t py) static Int_t px1,px2,py1,py2; static Int_t pxold, pyold, px1old, py1old, px2old, py2old; static Int_t dpx, dpy; - static Int_t *x=0, *y=0; + static std::vector x, y; Bool_t opaque = gPad->OpaqueMoving(); if (!gPad->IsEditable()) return; @@ -286,9 +287,9 @@ void TPolyLine::ExecuteEvent(Int_t event, Int_t px, Int_t py) ipoint = -1; - if (x || y) break; - x = new Int_t[np+1]; - y = new Int_t[np+1]; + if (!x.empty() || !y.empty()) break; + x.resize(np+1, 0); + y.resize(np+1, 0); for (i=0;iXtoAbsPixel(gPad->XtoPad(fX[i])); pyp = gPad->YtoAbsPixel(gPad->YtoPad(fY[i])); @@ -423,7 +424,7 @@ void TPolyLine::ExecuteEvent(Int_t event, Int_t px, Int_t py) pyold = TMath::Max(pyold, py2); pyold = TMath::Min(pyold, py1); } - if (x && y) { + if (!x.empty() && !y.empty()) { if (middle) { for(i=0;iPadtoX(gPad->AbsPixeltoX(x[i]+dpx)); @@ -458,7 +459,7 @@ void TPolyLine::ExecuteEvent(Int_t event, Int_t px, Int_t py) ymax + dyr*gPad->GetTopMargin()); gPad->RangeAxis(xmin, ymin, xmax, ymax); - if (x && y) { + if (!x.empty() && !y.empty()) { if (middle) { for(i=0;iPadtoX(gPad->AbsPixeltoX(x[i]+dpx)); @@ -468,8 +469,8 @@ void TPolyLine::ExecuteEvent(Int_t event, Int_t px, Int_t py) fX[ipoint] = gPad->PadtoX(gPad->AbsPixeltoX(pxold)); fY[ipoint] = gPad->PadtoY(gPad->AbsPixeltoY(pyold)); } - delete [] x; x = 0; - delete [] y; y = 0; + x.clear(); + y.clear(); } gPad->Modified(kTRUE); gVirtualX->SetLineColor(-1); From 7488ebdbce62eee271f85e969323f3be2aebfc51 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 23 Jun 2022 14:08:21 +0200 Subject: [PATCH 009/104] Use std::unique_ptr for temporary TBox in TPad::ExecuteEventAxis --- graf2d/gpad/src/TPad.cxx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/graf2d/gpad/src/TPad.cxx b/graf2d/gpad/src/TPad.cxx index 396253ca23030..69105cbee5371 100644 --- a/graf2d/gpad/src/TPad.cxx +++ b/graf2d/gpad/src/TPad.cxx @@ -12,6 +12,7 @@ #include #include #include +#include #include "TROOT.h" #include "TBuffer.h" @@ -2293,7 +2294,7 @@ void TPad::ExecuteEventAxis(Int_t event, Int_t px, Int_t py, TAxis *axis) Int_t bin1, bin2, first, last; Double_t temp, xmin,xmax; Bool_t opaque = gPad->OpaqueMoving(); - static TBox *zoombox; + static std::unique_ptr zoombox; Double_t zbx1=0,zbx2=0,zby1=0,zby2=0; // The CONT4 option, used to paint TH2, is a special case; it uses a 3D @@ -2365,7 +2366,7 @@ void TPad::ExecuteEventAxis(Int_t event, Int_t px, Int_t py, TAxis *axis) zby1 = TMath::Power(10,zby1); zby2 = TMath::Power(10,zby2); } - zoombox = new TBox(zbx1, zby1, zbx2, zby2); + zoombox = std::make_unique(zbx1, zby1, zbx2, zby2); Int_t ci = TColor::GetColor("#7d7dff"); TColor *zoomcolor = gROOT->GetColor(ci); if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002); @@ -2452,10 +2453,8 @@ void TPad::ExecuteEventAxis(Int_t event, Int_t px, Int_t py, TAxis *axis) case kButton1Up: if (gROOT->IsEscaped()) { gROOT->SetEscape(kFALSE); - if (opaque && zoombox) { - zoombox->Delete(); - zoombox = 0; - } + if (opaque && zoombox) + zoombox.reset(); break; } @@ -2603,8 +2602,7 @@ void TPad::ExecuteEventAxis(Int_t event, Int_t px, Int_t py, TAxis *axis) gVirtualX->SetLineColor(-1); } else { if (zoombox) { - zoombox->Delete(); - zoombox = 0; + zoombox.reset(); gPad->Modified(); gPad->Update(); } From 0c34796b6e4a614cc201fe18bade05fbd2a95fc0 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 23 Jun 2022 14:14:02 +0200 Subject: [PATCH 010/104] Use std::vector for temp array in TGraph::ExecuteEvent --- hist/histpainter/src/TGraphPainter.cxx | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/hist/histpainter/src/TGraphPainter.cxx b/hist/histpainter/src/TGraphPainter.cxx index 133a7310dd514..e55569aac80ee 100644 --- a/hist/histpainter/src/TGraphPainter.cxx +++ b/hist/histpainter/src/TGraphPainter.cxx @@ -37,6 +37,7 @@ #include "TRegexp.h" #include "strlcpy.h" #include "snprintf.h" +#include Double_t *gxwork, *gywork, *gxworkl, *gyworkl; Int_t TGraphPainter::fgMaxPointsPerLine = 50; @@ -836,7 +837,7 @@ void TGraphPainter::ExecuteEventHelper(TGraph *theGraph, Int_t event, Int_t px, static Int_t px1,px2,py1,py2; static Int_t pxold, pyold, px1old, py1old, px2old, py2old; static Int_t dpx, dpy; - static Int_t *x=0, *y=0; + static std::vector x, y; Bool_t opaque = gPad->OpaqueMoving(); if (!theGraph->IsEditable() || theGraph->InheritsFrom(TGraphPolar::Class())) { @@ -861,9 +862,9 @@ void TGraphPainter::ExecuteEventHelper(TGraph *theGraph, Int_t event, Int_t px, ipoint = -1; - if (x || y) break; - x = new Int_t[theNpoints+1]; - y = new Int_t[theNpoints+1]; + if (!x.empty() || !y.empty()) break; + x.resize(theNpoints+1); + y.resize(theNpoints+1); for (i=0;iXtoAbsPixel(gPad->XtoPad(theX[i])); pyp = gPad->YtoAbsPixel(gPad->YtoPad(theY[i])); @@ -1013,8 +1014,8 @@ void TGraphPainter::ExecuteEventHelper(TGraph *theGraph, Int_t event, Int_t px, pyold = py; for(i=0;iPadtoX(gPad->AbsPixeltoX(x[i]+dpx)); - if (y) theY[i] = gPad->PadtoY(gPad->AbsPixeltoY(y[i]+dpy)); + if (!x.empty()) theX[i] = gPad->PadtoX(gPad->AbsPixeltoX(x[i]+dpx)); + if (!y.empty()) theY[i] = gPad->PadtoY(gPad->AbsPixeltoY(y[i]+dpy)); } } else { pxold = px; @@ -1047,8 +1048,8 @@ void TGraphPainter::ExecuteEventHelper(TGraph *theGraph, Int_t event, Int_t px, if (gROOT->IsEscaped()) { gROOT->SetEscape(kFALSE); - delete [] x; x = 0; - delete [] y; y = 0; + x.clear(); + y.clear(); break; } @@ -1074,8 +1075,8 @@ void TGraphPainter::ExecuteEventHelper(TGraph *theGraph, Int_t event, Int_t px, if (middle) { for(i=0;iPadtoX(gPad->AbsPixeltoX(x[i]+dpx)); - if (y) theY[i] = gPad->PadtoY(gPad->AbsPixeltoY(y[i]+dpy)); + if (!x.empty()) theX[i] = gPad->PadtoX(gPad->AbsPixeltoX(x[i]+dpx)); + if (!y.empty()) theY[i] = gPad->PadtoY(gPad->AbsPixeltoY(y[i]+dpy)); } } else { theX[ipoint] = gPad->PadtoX(gPad->AbsPixeltoX(pxold)); @@ -1093,8 +1094,8 @@ void TGraphPainter::ExecuteEventHelper(TGraph *theGraph, Int_t event, Int_t px, } } badcase = kFALSE; - delete [] x; x = 0; - delete [] y; y = 0; + x.clear(); + y.clear(); gPad->Modified(kTRUE); gVirtualX->SetLineColor(-1); } From 045129cafc16887cd5ef2e273f69687fdeb43d12 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 23 Jun 2022 14:15:57 +0200 Subject: [PATCH 011/104] Use unique_ptr for temp object in TH1::ExecuteEvent --- hist/histpainter/src/THistPainter.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index 0b065eeb8f2f4..60bc4eff2b2b5 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -14,6 +14,7 @@ #include #include #include +#include #include "TROOT.h" #include "TSystem.h" @@ -3471,7 +3472,7 @@ void THistPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py) if (!gPad) return; static Int_t bin, px1, py1, px2, py2, pyold; - static TBox *zoombox = nullptr; + static std::unique_ptr zoombox; Double_t zbx1,zbx2,zby1,zby2; Int_t bin1, bin2; @@ -3538,7 +3539,7 @@ void THistPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py) zby2 = TMath::Power(10,zby2); } if (zoombox) Error("ExecuteEvent", "Last zoom box was not deleted"); - zoombox = new TBox(zbx1, zby1, zbx2, zby2); + zoombox = std::make_unique(zbx1, zby1, zbx2, zby2); Int_t ci = TColor::GetColor("#7d7dff"); TColor *zoomcolor = gROOT->GetColor(ci); if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002); @@ -3678,8 +3679,7 @@ void THistPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py) xaxis->SetRangeUser(x1, x2); yaxis->SetRangeUser(y1, y2); } - zoombox->Delete(); - zoombox = nullptr; + zoombox.reset(); } } gPad->Modified(kTRUE); From 3168b3156344c3f539540ee0280e5eea025a2edd Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 23 Jun 2022 14:33:29 +0200 Subject: [PATCH 012/104] Use std::vector for static list of colors in TImagePalette --- graf2d/graf/src/TAttImage.cxx | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/graf2d/graf/src/TAttImage.cxx b/graf2d/graf/src/TAttImage.cxx index abea2490c201b..81d61cc5908fd 100644 --- a/graf2d/graf/src/TAttImage.cxx +++ b/graf2d/graf/src/TAttImage.cxx @@ -92,7 +92,7 @@ This class provides a way to edit the palette via a GUI. #include "TColor.h" #include "TMath.h" #include "TStyle.h" - +#include ClassImp(TPaletteEditor); ClassImp(TAttImage); @@ -171,10 +171,11 @@ class TWebPalette : public TImagePalette { Int_t *GetRootColors() override { - static Int_t *gRootColors = nullptr; - if (gRootColors) return gRootColors; + static std::vector gRootColors; + if (!gRootColors.empty()) + return gRootColors.data(); - gRootColors = new Int_t[216]; + gRootColors.resize(216); int i = 0; for (int r = 0; r < 6; r++) { @@ -185,7 +186,7 @@ class TWebPalette : public TImagePalette { } } } - return gRootColors; + return gRootColors.data(); } }; @@ -508,15 +509,16 @@ Int_t TImagePalette::FindColor(UShort_t r, UShort_t g, UShort_t b) Int_t *TImagePalette::GetRootColors() { - static Int_t *gRootColors = 0; - if (gRootColors) return gRootColors; + static std::vector gRootColors; + if (!gRootColors.empty()) + return gRootColors.data(); - gRootColors = new Int_t[fNumPoints]; + gRootColors.resize(fNumPoints); - for (UInt_t i = 0; i < fNumPoints; i++) { + for (UInt_t i = 0; i < fNumPoints; i++) gRootColors[i] = TColor::GetColor(fColorRed[i], fColorGreen[i], fColorBlue[i]); - } - return gRootColors; + + return gRootColors.data(); } //////////////////////////////////////////////////////////////////////////////// From 47593d6e526598ab8dcd3b7a9bee1bf97e2ac2d2 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 23 Jun 2022 14:41:42 +0200 Subject: [PATCH 013/104] Use std::unique_ptr for static objects in THistPainter --- hist/histpainter/src/THistPainter.cxx | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index 60bc4eff2b2b5..75a41c7257aa1 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -3153,7 +3153,7 @@ For more complex demo please see for example `$ROOTSYS/tutorials/tree/temperatur */ -TH1 *gCurrentHist = 0; +TH1 *gCurrentHist = nullptr; Hoption_t Hoption; Hparam_t Hparam; @@ -3163,8 +3163,7 @@ const Int_t kNMAX = 2000; const Int_t kMAXCONTOUR = 104; const UInt_t kCannotRotate = BIT(11); -static TBox *gXHighlightBox = 0; // highlight X box -static TBox *gYHighlightBox = 0; // highlight Y box +static std::unique_ptr gXHighlightBox, gYHighlightBox; // highlight X and Y box static TString gStringEntries; static TString gStringMean; @@ -3195,8 +3194,7 @@ ClassImp(THistPainter); THistPainter::THistPainter() { - - fH = 0; + fH = nullptr; fXaxis = 0; fYaxis = 0; fZaxis = 0; @@ -3206,8 +3204,8 @@ THistPainter::THistPainter() fNcuts = 0; fStack = 0; fLego = 0; - fPie = 0; - fGraph2DPainter = 0; + fPie = nullptr; + fGraph2DPainter = nullptr; fShowProjection = 0; fShowOption = ""; for (int i=0; iGetListOfFunctions(); TGraphDelaunay2D *dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D"); @@ -3871,8 +3866,8 @@ void THistPainter::SetHighlight() fXHighlightBin = -1; fYHighlightBin = -1; // delete previous highlight box - if (gXHighlightBox) { gXHighlightBox->Delete(); gXHighlightBox = 0; } - if (gYHighlightBox) { gYHighlightBox->Delete(); gYHighlightBox = 0; } + if (gXHighlightBox) gXHighlightBox.reset(); + if (gYHighlightBox) gYHighlightBox.reset(); // emit Highlighted() signal (user can check on disabled) if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, fH, fXHighlightBin, fYHighlightBin); } @@ -3963,7 +3958,7 @@ void THistPainter::PaintHighlightBin(Option_t * /*option*/) } if (!gXHighlightBox) { - gXHighlightBox = new TBox(hbx1, hby1, hbx2, hby2); + gXHighlightBox = std::make_unique(hbx1, hby1, hbx2, hby2); gXHighlightBox->SetBit(kCannotPick); gXHighlightBox->SetFillColor(TColor::GetColor("#9797ff")); if (!TCanvas::SupportAlpha()) gXHighlightBox->SetFillStyle(3001); @@ -3986,7 +3981,7 @@ void THistPainter::PaintHighlightBin(Option_t * /*option*/) hby2 = fYaxis->GetBinUpEdge(fYHighlightBin); if (!gYHighlightBox) { - gYHighlightBox = new TBox(hbx1, hby1, hbx2, hby2); + gYHighlightBox = std::make_unique(hbx1, hby1, hbx2, hby2); gYHighlightBox->SetBit(kCannotPick); gYHighlightBox->SetFillColor(gXHighlightBox->GetFillColor()); gYHighlightBox->SetFillStyle(gXHighlightBox->GetFillStyle()); @@ -4505,7 +4500,7 @@ void THistPainter::Paint(Option_t *option) return; } else { if (fPie) delete fPie; - fPie = 0; + fPie = nullptr; } fXbuf = new Double_t[kNMAX]; From 98d05db493eff4ca0f569fb22579afee6a7a24ab Mon Sep 17 00:00:00 2001 From: Olivier Couet Date: Fri, 24 Jun 2022 08:57:57 +0200 Subject: [PATCH 014/104] [skip-ci] put CONT5 option in the right place (#10819) --- hist/hist/src/TGraph2D.cxx | 1 + hist/histpainter/src/THistPainter.cxx | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/hist/hist/src/TGraph2D.cxx b/hist/hist/src/TGraph2D.cxx index 7f87417b95073..df29080d235fa 100644 --- a/hist/hist/src/TGraph2D.cxx +++ b/hist/hist/src/TGraph2D.cxx @@ -106,6 +106,7 @@ Specific drawing options can be used to paint a TGraph2D: | "P0" | Draw a circle at each vertex. Each circle background is white. | | "PCOL" | Draw a marker at each vertex. The color of each marker is defined according to its Z position. | | "LINE" | Draw a 3D polyline. | +| "CONT5" | Draw a contour plot using Delaunay triangles.| A TGraph2D can be also drawn with any options valid to draw a 2D histogram (like `COL`, `SURF`, `LEGO`, `CONT` etc..). diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index 75a41c7257aa1..d86728442f3a9 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -302,7 +302,6 @@ using `TH1::GetOption`: | "CONT2" | Draw a contour plot using the same line style for all contours.| | "CONT3" | Draw a contour plot using fill area colors.| | "CONT4" | Draw a contour plot using surface colors (SURF option at theta = 0).| -| "CONT5" | (TGraph2D only) Draw a contour plot using Delaunay triangles.| | "LIST" | Generate a list of TGraph objects for each contour.| | "SAME0" | Same as "SAME" but do not use the z-axis range of the first plot. | | "SAMES0" | Same as "SAMES" but do not use the z-axis range of the first plot. | @@ -1739,8 +1738,6 @@ The following contour options are supported: | "CONT2" | Draw a contour plot using the line styles (1 to 5) to distinguish contours. | | "CONT3" | Draw a contour plot using the same line style for all contours. | | "CONT4" | Draw a contour plot using surface colors (`SURF` option at theta = 0). | -| "CONT5" | Draw a contour plot using Delaunay triangles. | - The following example shows a 2D histogram plotted with the option From fe8d738d2952d231907cfd080747a898fedaf11d Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Thu, 23 Jun 2022 16:41:14 +0200 Subject: [PATCH 015/104] [RF] Delete wrongly implemented copy assignment operator of RooPolyFunc In commit 196ef3b, `operator=` for the RooPolyFunc was implemented, but it was implemented wrognly: it used the assignment operator the the proxy collections, which does value syncronization and not copy assignment! It's better to delete the copy assignment for RooPolyFunc, because copy/move assignment of RooFit objects is very badly supported. --- roofit/roofitcore/inc/RooPolyFunc.h | 3 ++- roofit/roofitcore/src/RooPolyFunc.cxx | 14 -------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/roofit/roofitcore/inc/RooPolyFunc.h b/roofit/roofitcore/inc/RooPolyFunc.h index fa2dd1a1c6f72..c6e12096951fc 100644 --- a/roofit/roofitcore/inc/RooPolyFunc.h +++ b/roofit/roofitcore/inc/RooPolyFunc.h @@ -31,7 +31,8 @@ class RooPolyFunc : public RooAbsReal { RooPolyFunc(const char *name, const char *title, RooAbsReal &x, RooAbsReal &y, const RooAbsCollection &coefList); RooPolyFunc(const char *name, const char *title, const RooAbsCollection &vars); RooPolyFunc(const RooPolyFunc &other, const char *name = 0); - RooPolyFunc &operator=(const RooPolyFunc &other); + RooPolyFunc &operator=(const RooPolyFunc &other) = delete; + RooPolyFunc &operator=(RooPolyFunc &&other) = delete; TObject *clone(const char *newname) const override { return new RooPolyFunc(*this, newname); } void addTerm(double coefficient); diff --git a/roofit/roofitcore/src/RooPolyFunc.cxx b/roofit/roofitcore/src/RooPolyFunc.cxx index 52e3c930400b6..8a46dc5213f2f 100644 --- a/roofit/roofitcore/src/RooPolyFunc.cxx +++ b/roofit/roofitcore/src/RooPolyFunc.cxx @@ -160,20 +160,6 @@ RooPolyFunc::RooPolyFunc(const RooPolyFunc &other, const char *name) } } -//////////////////////////////////////////////////////////////////////////////// -/// Assignment operator - -RooPolyFunc &RooPolyFunc::operator=(const RooPolyFunc &other) -{ - RooAbsReal::operator=(other); - _vars = other._vars; - - for (auto const &term : other._terms) { - _terms.emplace_back(std::make_unique(term->GetName(), this, *term)); - } - return *this; -} - //////////////////////////////////////////////////////////////////////////////// /// Evaluate value of Polynomial. double RooPolyFunc::evaluate() const From dbc968107d66863e871d3c4a3f3c067c8b7c104e Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Thu, 23 Jun 2022 16:45:40 +0200 Subject: [PATCH 016/104] [RF] Second attempt to fix schema evolution for old RooProduct versions There was a bug in a schema evolution rule for a very old RooProduct version, where a `RooSetProxy` member was replaced by a `RooListProxy`. The problem was that only the content was copied to the new proxy list, not the other members. This lead to an invalid state for the RooSetProxy, because it had no registered owner. Commit aa55e5c5 attempted to fix the problem, but the fix used the `RooArgList::operator=`, which doesn't implement copy assignment, but value synchronization! So the target proxy list was empty after calling it. Therefore, one the RooCollectionProxy needs to be extended with something that does exactly what the schema evolution requires: setting the owner of the proxy and adding all elements without registering the elements as servers (the server lists are copied separately by IO). A new member function initializeAfterIOConstructor` was added to the RooCollectionProxy for this. In the initial attempt to the fix, it was thought the original problem was only that the proxy owner was not set in the proxy, but actually the _proxyList only contained `nullptr` after reading and old RooProduct! The reason for that is the reason for which `RooAbsArg::ioStreamerPass2()` exists (quoting from its documentation): > second pass is typically needed when evolving data member of > RooAbsArg-derived classes that are container classes with references > to other members, which may not yet be 'live' in the first > ioStreamer() evolution pass. Hence, `RooProduct` needs to override `ioStreamerPass2()` and set the proxy list correctly there, which is also done in this commit. --- roofit/roofitcore/inc/LinkDef.h | 10 +++---- roofit/roofitcore/inc/RooCollectionProxy.h | 26 ++++++++++++++++-- roofit/roofitcore/inc/RooProduct.h | 2 ++ roofit/roofitcore/src/RooProduct.cxx | 31 +++++++++++++++++++--- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/roofit/roofitcore/inc/LinkDef.h b/roofit/roofitcore/inc/LinkDef.h index ce15e7079f58b..28c591862d405 100644 --- a/roofit/roofitcore/inc/LinkDef.h +++ b/roofit/roofitcore/inc/LinkDef.h @@ -167,14 +167,10 @@ #pragma link C++ class RooProdGenContext+ ; #pragma link C++ class RooProduct+ ; #pragma read sourceClass="RooProduct" targetClass="RooProduct" version="[1]" \ - source="RooSetProxy _compRSet" target="_compRSet" \ + source="RooSetProxy _compRSet; RooSetProxy _compCSet" target="_compRSet, _compCSet" \ code="{ \ - _compRSet = RooListProxy(onfile._compRSet.GetName(), newObj, onfile._compRSet) ; \ - }" -#pragma read sourceClass="RooProduct" targetClass="RooProduct" version="[1]" \ - source="RooSetProxy _compCSet" target="_compCSet" \ - code="{ \ - _compCSet = RooListProxy(onfile._compCSet.GetName(), newObj, onfile._compCSet) ; \ + _compRSet.initializeAfterIOConstructor(newObj, onfile._compRSet) ; \ + _compCSet.initializeAfterIOConstructor(newObj, onfile._compCSet) ; \ }" #pragma link C++ class RooPullVar+ ; #pragma link C++ class RooQuasiRandomGenerator+ ; diff --git a/roofit/roofitcore/inc/RooCollectionProxy.h b/roofit/roofitcore/inc/RooCollectionProxy.h index 9c01e3ecf893f..e75d2cd617d5f 100644 --- a/roofit/roofitcore/inc/RooCollectionProxy.h +++ b/roofit/roofitcore/inc/RooCollectionProxy.h @@ -53,12 +53,34 @@ class RooCollectionProxy final : public RooCollection_t, public RooAbsProxy { } /// Copy constructor. - template + template RooCollectionProxy(const char *inName, RooAbsArg *owner, const Other_t &other) : RooCollection_t(other, inName), _owner(owner), _defValueServer(other.defValueServer()), _defShapeServer(other.defShapeServer()) { - _owner->registerProxy(*this); + _owner->registerProxy(*this); + } + + /// Initializes this RooCollection proxy from another proxy. Should not be + /// considered part of the public interface, only to be used by IO. + template + void initializeAfterIOConstructor(RooAbsArg *owner, const Other_t &other) + { + + // Copy all attributes from "other" + _owner = owner; + _defValueServer = other.defValueServer(); + _defShapeServer = other.defShapeServer(); + RooCollection_t::setName(other.GetName()); + + // Add the elements. This should not be done with + // RooCollectionProxy::add(), but with the base class method. Otherwise, + // _owner->addServer() is called when adding each element, which we don't + // want for IO because the list of servers are already filled when + // reading the server list of the object in the file. + RooCollection_t::add(other); + + // Don't do _owner->registerProxy(*this) here! The proxy list will also be copied separately. } ~RooCollectionProxy() override diff --git a/roofit/roofitcore/inc/RooProduct.h b/roofit/roofitcore/inc/RooProduct.h index eb3d63899d34d..12c69ca55a7b1 100644 --- a/roofit/roofitcore/inc/RooProduct.h +++ b/roofit/roofitcore/inc/RooProduct.h @@ -62,6 +62,8 @@ class RooProduct : public RooAbsReal { protected: + void ioStreamerPass2() override ; + RooListProxy _compRSet ; RooListProxy _compCSet ; diff --git a/roofit/roofitcore/src/RooProduct.cxx b/roofit/roofitcore/src/RooProduct.cxx index e7fb894a7beb2..b26c6aa7a38e6 100644 --- a/roofit/roofitcore/src/RooProduct.cxx +++ b/roofit/roofitcore/src/RooProduct.cxx @@ -533,7 +533,34 @@ void RooProduct::printMetaArgs(ostream& os) const } +void RooProduct::ioStreamerPass2() { + RooAbsReal::ioStreamerPass2(); // call the baseclass method + if(numProxies() < 2) { + throw std::runtime_error("RooProduct::ioStreamerPass2(): the number of proxies in the proxy list should be at leat 2!"); + } + + // If the proxy data members are evolved by schema evolution, the proxy list + // that references them will contain null pointers because the evolved + // members are only created after the proxy list. That's why we have to set + // them manually in that case. But to make sure we don't overwrite valid + // proxies, an exception will be thrown if the proxy list constains + // unexpected values. + RooAbsProxy * p0 = getProxy(0); + if(p0 != &_compRSet) { + if(p0) { + throw std::runtime_error("RooProduct::ioStreamerPass2(): the first proxy unexpectedly wasn't the compRSet!"); + } + _proxyList.AddAt(&_compRSet, 0); + } + RooAbsProxy * p1 = getProxy(1); + if(p1 != &_compCSet) { + if(p1) { + throw std::runtime_error("RooProduct::ioStreamerPass2(): the second proxy unexpectedly wasn't the compCSet!"); + } + _proxyList.AddAt(&_compCSet, 1); + } +} namespace { @@ -564,7 +591,3 @@ void dump_map(ostream& os, RPPMIter i, RPPMIter end) } } - - - - From bac3ea9ad660c1e9f432bc44242673636d552f35 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Thu, 23 Jun 2022 18:06:25 +0200 Subject: [PATCH 017/104] [RF] Call base class method in RooHistFunc::ioStreamerPass2() The documentation of `RooAbsArg::ioStreamerPass2()` says: > Classes may overload this function, but must call the base method in > the overloaded call to ensure base evolution is handled properly This was not done in the overload in RooHistFunc, which is a mistake that probably leads to backwards compatibility errors that are undetected to far. --- roofit/roofitcore/src/RooHistFunc.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roofit/roofitcore/src/RooHistFunc.cxx b/roofit/roofitcore/src/RooHistFunc.cxx index 6754878b42e62..479f4bc6e083b 100644 --- a/roofit/roofitcore/src/RooHistFunc.cxx +++ b/roofit/roofitcore/src/RooHistFunc.cxx @@ -564,6 +564,8 @@ void RooHistFunc::Streamer(TBuffer &R__b) void RooHistFunc::ioStreamerPass2() { + RooAbsReal::ioStreamerPass2(); // call the baseclass method + if (_histObsList.empty()) { _histObsList.addClone(_depList) ; } From 7bf31791a7c18ba6494c9aacff62312d877b5117 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Thu, 23 Jun 2022 18:10:21 +0200 Subject: [PATCH 018/104] [RF] Disable misleading copy assignment for RooCollectionProxy Two of the previous commits have shown that copy assignment for RooCollectionProxy is dangerous because it behaves unexpectedly. However, it is not clear how it *should* behave. Should default assignment be used? But then, it will use the assignment operators of the RooFit collections, which actually don't do assignment, but value syncronization! Should it be re-implemented to be actual assignment? That would be inconsistent with the base class! So it's better to not support it at all. --- roofit/roofitcore/inc/RooCollectionProxy.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/roofit/roofitcore/inc/RooCollectionProxy.h b/roofit/roofitcore/inc/RooCollectionProxy.h index e75d2cd617d5f..21447276c6f1c 100644 --- a/roofit/roofitcore/inc/RooCollectionProxy.h +++ b/roofit/roofitcore/inc/RooCollectionProxy.h @@ -83,6 +83,15 @@ class RooCollectionProxy final : public RooCollection_t, public RooAbsProxy { // Don't do _owner->registerProxy(*this) here! The proxy list will also be copied separately. } + // Assignment is deleted because it is not clear how it should behave. + // Should default assignment be used? But then, it will use the assignment + // operators of the RooFit collections, which actually don't do assignment, + // but value syncronization! Should it be re-implemented to be actual + // assignment? That would be inconsistent with the base class! So it's + // better to not support it at all. + RooCollectionProxy& operator=(RooCollectionProxy const& other) = delete; + RooCollectionProxy& operator=(RooCollectionProxy && other) = delete; + ~RooCollectionProxy() override { if (_owner) From 678c5b4ad95f04ad0297c493d75faf4ad02ccd12 Mon Sep 17 00:00:00 2001 From: Giovanna Lazzari Miotto Date: Wed, 22 Jun 2022 15:29:30 +0200 Subject: [PATCH 019/104] [ntuple,daos] Permanent pool EQs; parent events This commit renames and refactors `RDaosEventQueue` to include: - Parent events that are responsible for a batch of asynchronous events originating from a single RW call. This simplifies polling, which is a waiting call on the batch of requests sent under that parent that are inflight (`WaitOnParentBarrier`, which sets a parent event barrier and waits for all children launched before it to complete). - Poolwide event queues that are shared among its underlying containers and persist between RW calls. This eliminates the significant overhead behind instantiating new queues for each call to `VectorReadWrite`. - Queue management obeying RAII principle. - Better handling of synchronous events in `FetchUpdateArgs` (the default behavior). The event is an optional attribute which yields a nullptr to DAOS fetch/update calls in such cases, indicating the request is blocking. - The functions `daos_event_test` and `daos_event_parent_barrier`, used for polling and sending parent events respectively, to `libdaos_mock`. Co-authored-by: Giovanna Lazzari Miotto Co-authored-by: Javier Lopez-Gomez --- tree/ntuple/v7/inc/ROOT/RDaos.hxx | 83 ++++++++++++------- tree/ntuple/v7/inc/ROOT/libdaos_mock/daos.h | 2 + tree/ntuple/v7/src/RDaos.cxx | 77 ++++++++++------- .../v7/src/libdaos_mock/libdaos_mock.cxx | 12 +++ 4 files changed, 112 insertions(+), 62 deletions(-) diff --git a/tree/ntuple/v7/inc/ROOT/RDaos.hxx b/tree/ntuple/v7/inc/ROOT/RDaos.hxx index 081c547943b50..36410b1b4e646 100644 --- a/tree/ntuple/v7/inc/ROOT/RDaos.hxx +++ b/tree/ntuple/v7/inc/ROOT/RDaos.hxx @@ -26,6 +26,7 @@ #include #include #include +#include #ifndef DAOS_UUID_STR_SIZE #define DAOS_UUID_STR_SIZE 37 @@ -35,6 +36,24 @@ namespace ROOT { namespace Experimental { namespace Detail { + +struct RDaosEventQueue { + daos_handle_t fQueue; + RDaosEventQueue(); + ~RDaosEventQueue(); + + /// \brief Sets event barrier for a given parent event and waits for the completion of all children launched before + /// the barrier (must have at least one child). + /// \return 0 on success; a DAOS error code otherwise (< 0). + int WaitOnParentBarrier(daos_event_t *ev_ptr); + /// \brief Reserve event in queue, optionally tied to a parent event. + /// \return 0 on success; a DAOS error code otherwise (< 0). + int InitializeEvent(daos_event_t *ev_ptr, daos_event_t *parent_ptr = nullptr); + /// \brief Release event data from queue. + /// \return 0 on success; a DAOS error code otherwise (< 0). + int FinalizeEvent(daos_event_t *ev_ptr); +}; + class RDaosContainer; /** @@ -47,6 +66,7 @@ private: daos_handle_t fPoolHandle{}; uuid_t fPoolUuid{}; std::string fPoolLabel{}; + std::unique_ptr fEventQueue; public: RDaosPool(const RDaosPool&) = delete; @@ -91,8 +111,9 @@ public: FetchUpdateArgs() = default; FetchUpdateArgs(const FetchUpdateArgs&) = delete; FetchUpdateArgs(FetchUpdateArgs&& fua); - FetchUpdateArgs(DistributionKey_t &d, AttributeKey_t &a, std::vector &v, daos_event_t *p = nullptr); - FetchUpdateArgs& operator=(const FetchUpdateArgs&) = delete; + FetchUpdateArgs(DistributionKey_t &d, AttributeKey_t &a, std::vector &v, bool is_async = false); + FetchUpdateArgs &operator=(const FetchUpdateArgs &) = delete; + daos_event_t *GetEventPointer(); /// \brief A `daos_key_t` is a type alias of `d_iov_t`. This type stores a pointer and a length. /// In order for `fDistributionKey` and `fIods` to point to memory that we own, `fDkey` and @@ -105,7 +126,7 @@ public: daos_iod_t fIods[1] = {}; d_sg_list_t fSgls[1] = {}; std::vector fIovs{}; - daos_event_t *fEv = nullptr; + std::optional fEvent{}; }; RDaosObject() = delete; @@ -143,19 +164,6 @@ public: std::string GetContainerUuid(); private: - struct DaosEventQueue { - std::size_t fSize; - std::unique_ptr fEvs; - daos_handle_t fQueue; - DaosEventQueue(std::size_t size); - ~DaosEventQueue(); - /** - \brief Wait for all events in this event queue to complete. - \return Number of events still in the queue. This should be 0 on success. - */ - int Poll(); - }; - daos_handle_t fContainerHandle{}; uuid_t fContainerUuid{}; std::string fContainerLabel{}; @@ -167,25 +175,40 @@ private: \param vec A `std::vector` that describes read/write operations to perform. \param cid The `daos_oclass_id_t` used to qualify OIDs. \param fn Either `std::mem_fn<&RDaosObject::Fetch>` (read) or `std::mem_fn<&RDaosObject::Update>` (write). - \return Number of requests that did not complete; this should be 0 after a successful call. + \return DAOS error code (< 0) in case of failure, 0 on success. */ template int VectorReadWrite(std::vector &vec, ObjClassId_t cid, Fn fn) { + using request_t = std::tuple, RDaosObject::FetchUpdateArgs>; + int ret; - DaosEventQueue eventQueue(vec.size()); - { - std::vector, RDaosObject::FetchUpdateArgs>> requests{}; - requests.reserve(vec.size()); - for (size_t i = 0; i < vec.size(); ++i) { - requests.push_back(std::make_tuple(std::unique_ptr(new RDaosObject(*this, vec[i].fOid, cid.fCid)), - RDaosObject::FetchUpdateArgs{ - vec[i].fDistributionKey, vec[i].fAttributeKey, - vec[i].fIovs, &eventQueue.fEvs[i]})); - fn(std::get<0>(requests.back()).get(), std::get<1>(requests.back())); - } - ret = eventQueue.Poll(); + std::vector requests{}; + requests.reserve(vec.size()); + + // Initialize parent event used for grouping and waiting for completion of all requests + daos_event_t parent_event{}; + if ((ret = fPool->fEventQueue->InitializeEvent(&parent_event)) < 0) + return ret; + + for (size_t i = 0; i < vec.size(); ++i) { + requests.push_back(std::make_tuple(std::make_unique(*this, vec[i].fOid, cid.fCid), + RDaosObject::FetchUpdateArgs{vec[i].fDistributionKey, vec[i].fAttributeKey, + vec[i].fIovs, /*is_async=*/true})); + + if ((ret = fPool->fEventQueue->InitializeEvent(std::get<1>(requests.back()).GetEventPointer(), + &parent_event)) < 0) + return ret; + + // Launch operation + if ((ret = fn(std::get<0>(requests.back()).get(), std::get<1>(requests.back()))) < 0) + return ret; } - return ret; + + // Sets parent barrier and waits for all children launched before it. + if ((ret = fPool->fEventQueue->WaitOnParentBarrier(&parent_event)) < 0) + return ret; + + return fPool->fEventQueue->FinalizeEvent(&parent_event); } public: diff --git a/tree/ntuple/v7/inc/ROOT/libdaos_mock/daos.h b/tree/ntuple/v7/inc/ROOT/libdaos_mock/daos.h index 84af6941fe304..7f6dbcf1d5516 100644 --- a/tree/ntuple/v7/inc/ROOT/libdaos_mock/daos.h +++ b/tree/ntuple/v7/inc/ROOT/libdaos_mock/daos.h @@ -96,6 +96,8 @@ int daos_eq_create(daos_handle_t *eqh); int daos_eq_destroy(daos_handle_t eqh, int flags); int daos_eq_poll(daos_handle_t eqh, int wait_running, int64_t timeout, unsigned int nevents, daos_event_t **events); +int daos_event_test(daos_event_t *ev, int64_t timeout, bool *flag); +int daos_event_parent_barrier(daos_event_t *ev); int daos_event_init(daos_event_t *ev, daos_handle_t eqh, daos_event_t *parent); int daos_event_fini(daos_event_t *ev); diff --git a/tree/ntuple/v7/src/RDaos.cxx b/tree/ntuple/v7/src/RDaos.cxx index 528fc8c111194..5ecd7d61fcabf 100644 --- a/tree/ntuple/v7/src/RDaos.cxx +++ b/tree/ntuple/v7/src/RDaos.cxx @@ -37,6 +37,8 @@ ROOT::Experimental::Detail::RDaosPool::RDaosPool(std::string_view poolId) throw RException(R__FAIL("daos_pool_connect: error: " + std::string(d_errstr(err)))); } uuid_copy(fPoolUuid, poolInfo.pi_uuid); + + fEventQueue = std::make_unique(); } ROOT::Experimental::Detail::RDaosPool::~RDaosPool() @@ -61,19 +63,21 @@ std::string ROOT::Experimental::Detail::RDaosObject::ObjClassId::ToString() cons return std::string{name}; } - -ROOT::Experimental::Detail::RDaosObject::FetchUpdateArgs::FetchUpdateArgs(FetchUpdateArgs&& fua) - : fDkey(fua.fDkey), fAkey(fua.fAkey), - fIods{fua.fIods[0]}, fSgls{fua.fSgls[0]}, fIovs(std::move(fua.fIovs)), fEv(fua.fEv) +ROOT::Experimental::Detail::RDaosObject::FetchUpdateArgs::FetchUpdateArgs(FetchUpdateArgs &&fua) + : fDkey(fua.fDkey), fAkey(fua.fAkey), fIods{fua.fIods[0]}, fSgls{fua.fSgls[0]}, fIovs(std::move(fua.fIovs)), + fEvent(std::move(fua.fEvent)) { d_iov_set(&fDistributionKey, &fDkey, sizeof(fDkey)); d_iov_set(&fIods[0].iod_name, &fAkey, sizeof(fAkey)); } -ROOT::Experimental::Detail::RDaosObject::FetchUpdateArgs::FetchUpdateArgs -(DistributionKey_t &d, AttributeKey_t &a, std::vector &v, daos_event_t *p) - : fDkey(d), fAkey(a), fIovs(v), fEv(p) +ROOT::Experimental::Detail::RDaosObject::FetchUpdateArgs::FetchUpdateArgs(DistributionKey_t &d, AttributeKey_t &a, + std::vector &v, bool is_async) + : fDkey(d), fAkey(a), fIovs(v) { + if (is_async) + fEvent.emplace(); + d_iov_set(&fDistributionKey, &fDkey, sizeof(fDkey)); d_iov_set(&fIods[0].iod_name, &fAkey, sizeof(fAkey)); @@ -88,6 +92,11 @@ ROOT::Experimental::Detail::RDaosObject::FetchUpdateArgs::FetchUpdateArgs fSgls[0].sg_iovs = fIovs.data(); } +daos_event_t *ROOT::Experimental::Detail::RDaosObject::FetchUpdateArgs::GetEventPointer() +{ + return fEvent ? &(fEvent.value()) : nullptr; +} + ROOT::Experimental::Detail::RDaosObject::RDaosObject(RDaosContainer &container, daos_obj_id_t oid, ObjClassId cid) { @@ -107,47 +116,51 @@ ROOT::Experimental::Detail::RDaosObject::~RDaosObject() int ROOT::Experimental::Detail::RDaosObject::Fetch(FetchUpdateArgs &args) { args.fIods[0].iod_size = (daos_size_t)DAOS_REC_ANY; - return daos_obj_fetch(fObjectHandle, DAOS_TX_NONE, - DAOS_COND_DKEY_FETCH | DAOS_COND_AKEY_FETCH, - &args.fDistributionKey, 1, args.fIods, args.fSgls, nullptr, args.fEv); + return daos_obj_fetch(fObjectHandle, DAOS_TX_NONE, DAOS_COND_DKEY_FETCH | DAOS_COND_AKEY_FETCH, + &args.fDistributionKey, 1, args.fIods, args.fSgls, nullptr, args.GetEventPointer()); } int ROOT::Experimental::Detail::RDaosObject::Update(FetchUpdateArgs &args) { - return daos_obj_update(fObjectHandle, DAOS_TX_NONE, 0, &args.fDistributionKey, 1, - args.fIods, args.fSgls, args.fEv); + return daos_obj_update(fObjectHandle, DAOS_TX_NONE, 0, &args.fDistributionKey, 1, args.fIods, args.fSgls, + args.GetEventPointer()); } - //////////////////////////////////////////////////////////////////////////////// - -ROOT::Experimental::Detail::RDaosContainer::DaosEventQueue::DaosEventQueue(std::size_t size) - : fSize(size), fEvs(std::unique_ptr(new daos_event_t[size])) +ROOT::Experimental::Detail::RDaosEventQueue::RDaosEventQueue() { - daos_eq_create(&fQueue); - for (std::size_t i = 0; i < fSize; ++i) - daos_event_init(&fEvs[i], fQueue, nullptr); + if (int ret = daos_eq_create(&fQueue)) + throw RException(R__FAIL("daos_eq_create: error: " + std::string(d_errstr(ret)))); } -ROOT::Experimental::Detail::RDaosContainer::DaosEventQueue::~DaosEventQueue() { - for (std::size_t i = 0; i < fSize; ++i) - daos_event_fini(&fEvs[i]); +ROOT::Experimental::Detail::RDaosEventQueue::~RDaosEventQueue() +{ daos_eq_destroy(fQueue, 0); } -int ROOT::Experimental::Detail::RDaosContainer::DaosEventQueue::Poll() { - auto evp = std::unique_ptr(new daos_event_t*[fSize]); - std::size_t n = fSize; - while (n) { - int c; - if ((c = daos_eq_poll(fQueue, 0, DAOS_EQ_WAIT, n, evp.get())) < 0) - break; - n -= c; - } - return n; +int ROOT::Experimental::Detail::RDaosEventQueue::InitializeEvent(daos_event_t *ev_ptr, daos_event_t *parent_ptr) +{ + return daos_event_init(ev_ptr, fQueue, parent_ptr); +} + +int ROOT::Experimental::Detail::RDaosEventQueue::FinalizeEvent(daos_event_t *ev_ptr) +{ + return daos_event_fini(ev_ptr); } +int ROOT::Experimental::Detail::RDaosEventQueue::WaitOnParentBarrier(daos_event_t *ev_ptr) +{ + int err; + bool flag; + + if ((err = daos_event_parent_barrier(ev_ptr)) < 0) + return err; + + if ((err = daos_event_test(ev_ptr, DAOS_EQ_WAIT, &flag)) < 0) + return err; + return 0; +} //////////////////////////////////////////////////////////////////////////////// diff --git a/tree/ntuple/v7/src/libdaos_mock/libdaos_mock.cxx b/tree/ntuple/v7/src/libdaos_mock/libdaos_mock.cxx index 9793d8c7736cc..35599fae348ca 100644 --- a/tree/ntuple/v7/src/libdaos_mock/libdaos_mock.cxx +++ b/tree/ntuple/v7/src/libdaos_mock/libdaos_mock.cxx @@ -331,6 +331,18 @@ int daos_eq_poll(daos_handle_t /*eqh*/, int /*wait_running*/, int64_t /*timeout* return nevents; } +int daos_event_test(daos_event * /*ev*/, int64_t /*timeout*/, bool *flag) +{ + if (flag != nullptr) + *flag = true; + return 0; +} + +int daos_event_parent_barrier(daos_event_t * /*ev*/) +{ + return 0; +} + int daos_event_init(daos_event_t * /*ev*/, daos_handle_t /*eqh*/, daos_event_t * /*parent*/) { return 0; From 468d20a61107fb48daffcd9d5b3285627ccb84c1 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 23 Jun 2022 14:54:14 +0200 Subject: [PATCH 020/104] [histpainter] use std::vector for interim buffer Ensure that buffer will be deleted when painter is deleted --- hist/histpainter/inc/THistPainter.h | 4 +- hist/histpainter/src/THistPainter.cxx | 67 ++++++++++++++------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/hist/histpainter/inc/THistPainter.h b/hist/histpainter/inc/THistPainter.h index 46bb1a27b0b9d..f060487c3c0c3 100644 --- a/hist/histpainter/inc/THistPainter.h +++ b/hist/histpainter/inc/THistPainter.h @@ -57,8 +57,8 @@ class THistPainter : public TVirtualHistPainter { TPainter3dAlgorithms *fLego; ///< Pointer to a TPainter3dAlgorithms object TGraph2DPainter *fGraph2DPainter; ///< Pointer to a TGraph2DPainter object TPie *fPie; ///< Pointer to a TPie in case of option PIE - Double_t *fXbuf; ///< X buffer coordinates - Double_t *fYbuf; ///< Y buffer coordinates + std::vector fXbuf; ///< X buffer coordinates + std::vector fYbuf; ///< Y buffer coordinates Int_t fNcuts; ///< Number of graphical cuts Int_t fCutsOpt[kMaxCuts]; ///< Sign of each cut TCutG *fCuts[kMaxCuts]; ///< Pointers to graphical cuts diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index d86728442f3a9..b49380546c656 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -3192,21 +3192,19 @@ ClassImp(THistPainter); THistPainter::THistPainter() { fH = nullptr; - fXaxis = 0; - fYaxis = 0; - fZaxis = 0; - fFunctions = 0; - fXbuf = 0; - fYbuf = 0; + fXaxis = nullptr; + fYaxis = nullptr; + fZaxis = nullptr; + fFunctions = nullptr; fNcuts = 0; fStack = 0; - fLego = 0; + fLego = nullptr; fPie = nullptr; fGraph2DPainter = nullptr; fShowProjection = 0; fShowOption = ""; for (int i=0; iGetDimension() > 2) { PaintH3(option); fH->SetMinimum(minsav); @@ -4514,7 +4512,8 @@ void THistPainter::Paint(Option_t *option) Hparam = hparsave; } gCurrentHist = oldhist; - delete [] fXbuf; delete [] fYbuf; + fXbuf.clear(); + fYbuf.clear(); return; } TView *view = gPad->GetView(); @@ -4547,7 +4546,8 @@ void THistPainter::Paint(Option_t *option) } fH->SetMinimum(minsav); gCurrentHist = oldhist; - delete [] fXbuf; delete [] fYbuf; + fXbuf.clear(); + fYbuf.clear(); if (fH->GetDimension() == 1) { Hoption.Logy = logysav; Hoption.Logz = logzsav; @@ -4557,14 +4557,16 @@ void THistPainter::Paint(Option_t *option) if (Hoption.Bar >= 20) { PaintBarH(option); - delete [] fXbuf; delete [] fYbuf; + fXbuf.clear(); + fYbuf.clear(); return; } gPad->RangeAxisChanged(); //emit RangeAxisChanged() signal to sync axes // fill Hparam structure with histo parameters if (!PaintInit()) { - delete [] fXbuf; delete [] fYbuf; + fXbuf.clear(); + fYbuf.clear(); return; } @@ -4643,9 +4645,8 @@ void THistPainter::Paint(Option_t *option) } fH->SetMinimum(minsav); gCurrentHist = oldhist; - delete [] fXbuf; fXbuf = 0; - delete [] fYbuf; fYbuf = 0; - + fXbuf.clear(); + fYbuf.clear(); } //////////////////////////////////////////////////////////////////////////////// @@ -6630,7 +6631,7 @@ void THistPainter::Paint2DErrors(Option_t *) fYbuf[1] = Hparam.ymax; fXbuf[2] = Hparam.zmin; fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin()); - fLego = new TPainter3dAlgorithms(fXbuf, fYbuf); + fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); TView *view = gPad->GetView(); if (!view) { Error("Paint2DErrors", "no TView in current pad"); @@ -6772,7 +6773,7 @@ void THistPainter::Paint2DErrors(Option_t *) delete axis; } - delete fLego; fLego = 0; + delete fLego; fLego = nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -7496,7 +7497,7 @@ void THistPainter::PaintH3Box(Int_t iopt) fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst()); fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast()); - fLego = new TPainter3dAlgorithms(fXbuf, fYbuf); + fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); // Set view TView *view = gPad->GetView(); @@ -7679,7 +7680,7 @@ void THistPainter::PaintH3BoxRaster() fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst()); fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast()); - fLego = new TPainter3dAlgorithms(fXbuf, fYbuf); + fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); // Set view TView *view = gPad->GetView(); @@ -7881,7 +7882,7 @@ void THistPainter::PaintH3Iso() s[1] = 0.5*s[0]; s[2] = 1.5*s[0]; - fLego = new TPainter3dAlgorithms(fXbuf, fYbuf); + fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); TView *view = gPad->GetView(); if (!view) { @@ -8013,7 +8014,7 @@ void THistPainter::PaintLego(Option_t *) raster = 0; } - fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System); + fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data(), Hoption.System); Int_t nids = -1; TH1 * hid = NULL; @@ -8477,7 +8478,7 @@ void THistPainter::PaintScatterPlot(Option_t *option) if (k > 0) { for (Int_t loop=0; loop= kNMAX) { - gPad->PaintPolyMarker(marker, fXbuf, fYbuf); + gPad->PaintPolyMarker(marker, fXbuf.data(), fYbuf.data()); marker=0; } fXbuf[marker] = (random.Rndm()*xstep) + xk; @@ -8499,7 +8500,7 @@ void THistPainter::PaintScatterPlot(Option_t *option) } } } - if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf); + if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf.data(), fYbuf.data()); if (Hoption.Zscale) PaintPalette(); } @@ -9263,7 +9264,7 @@ void THistPainter::PaintSurface(Option_t *) fYbuf[2] = z2c; } - fLego = new TPainter3dAlgorithms(fXbuf, fYbuf, Hoption.System); + fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data(), Hoption.System); fLego->SetEdgeAtt(fH->GetLineColor(),fH->GetLineStyle(),fH->GetLineWidth(),0); fLego->SetFillColor(fH->GetFillColor()); @@ -9490,7 +9491,7 @@ void THistPainter::PaintTriangles(Option_t *option) fYbuf[2] = Hparam.zmax; } - fLego = new TPainter3dAlgorithms(fXbuf, fYbuf); + fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); TView *view = gPad->GetView(); if (!view) { Error("PaintTriangles", "no TView in current pad"); @@ -9902,7 +9903,7 @@ void THistPainter::PaintTH2PolyScatterPlot(Option_t *) loop = 0; while (loop= kNMAX) { - gPad->PaintPolyMarker(marker, fXbuf, fYbuf); + gPad->PaintPolyMarker(marker, fXbuf.data(), fYbuf.data()); marker=0; } xp = (random.Rndm()*xstep) + xk; @@ -9914,7 +9915,7 @@ void THistPainter::PaintTH2PolyScatterPlot(Option_t *) loop++; } } - if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf); + if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf.data(), fYbuf.data()); } // Paint the TMultiGraph bins. @@ -9926,7 +9927,7 @@ void THistPainter::PaintTH2PolyScatterPlot(Option_t *) loop = 0; while (loop= kNMAX) { - gPad->PaintPolyMarker(marker, fXbuf, fYbuf); + gPad->PaintPolyMarker(marker, fXbuf.data(), fYbuf.data()); marker=0; } xp = (random.Rndm()*xstep) + xk; @@ -9938,7 +9939,7 @@ void THistPainter::PaintTH2PolyScatterPlot(Option_t *) loop++; } } - if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf, fYbuf); + if (marker > 0) gPad->PaintPolyMarker(marker, fXbuf.data(), fYbuf.data()); } } PaintTH2PolyBins("l"); @@ -10118,7 +10119,7 @@ void THistPainter::PaintTF3() fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst()); fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast()); - fLego = new TPainter3dAlgorithms(fXbuf, fYbuf); + fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); TView *view = gPad->GetView(); if (!view) { @@ -10140,7 +10141,7 @@ void THistPainter::PaintTF3() fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMode1); - fLego->ImplicitFunction(fCurrentF3, fXbuf, fYbuf, fH->GetNbinsX(), + fLego->ImplicitFunction(fCurrentF3, fXbuf.data(), fYbuf.data(), fH->GetNbinsX(), fH->GetNbinsY(), fH->GetNbinsZ(), "BF"); From 8befe27310ace00fcd6f5d413660f7cf908f8ca0 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 23 Jun 2022 15:45:49 +0200 Subject: [PATCH 021/104] Fix memory leak with TGraph2DPainter allocated in hist painter All contour plots was not releasing that painter at the end --- hist/histpainter/inc/THistPainter.h | 39 ++++---- hist/histpainter/src/THistPainter.cxx | 138 ++++++++++++-------------- 2 files changed, 84 insertions(+), 93 deletions(-) diff --git a/hist/histpainter/inc/THistPainter.h b/hist/histpainter/inc/THistPainter.h index f060487c3c0c3..b2fb6158cedf6 100644 --- a/hist/histpainter/inc/THistPainter.h +++ b/hist/histpainter/inc/THistPainter.h @@ -26,6 +26,7 @@ #include #include +#include class TH1; @@ -49,25 +50,25 @@ struct THistRenderingRegion class THistPainter : public TVirtualHistPainter { protected: - TH1 *fH; ///< Pointer to histogram to paint - TAxis *fXaxis; ///< Pointer to X axis - TAxis *fYaxis; ///< Pointer to Y axis - TAxis *fZaxis; ///< Pointer to Z axis - TList *fFunctions; ///< Pointer to histogram list of functions - TPainter3dAlgorithms *fLego; ///< Pointer to a TPainter3dAlgorithms object - TGraph2DPainter *fGraph2DPainter; ///< Pointer to a TGraph2DPainter object - TPie *fPie; ///< Pointer to a TPie in case of option PIE - std::vector fXbuf; ///< X buffer coordinates - std::vector fYbuf; ///< Y buffer coordinates - Int_t fNcuts; ///< Number of graphical cuts - Int_t fCutsOpt[kMaxCuts]; ///< Sign of each cut - TCutG *fCuts[kMaxCuts]; ///< Pointers to graphical cuts - TList *fStack; ///< Pointer to stack of histograms (if any) - Int_t fShowProjection; ///< True if a projection must be drawn - TString fShowOption; ///< Option to draw the projection - Int_t fXHighlightBin; ///< X highlight bin - Int_t fYHighlightBin; ///< Y highlight bin - TF3 *fCurrentF3; ///< Current TF3 function + TH1 *fH; ///< Pointer to histogram to paint + TAxis *fXaxis; ///< Pointer to X axis + TAxis *fYaxis; ///< Pointer to Y axis + TAxis *fZaxis; ///< Pointer to Z axis + TList *fFunctions; ///< Pointer to histogram list of functions + std::unique_ptr fLego; ///< Pointer to a TPainter3dAlgorithms object + std::unique_ptr fGraph2DPainter; ///< Pointer to a TGraph2DPainter object + std::unique_ptr fPie; ///< Pointer to a TPie in case of option PIE + std::vector fXbuf; ///< X buffer coordinates + std::vector fYbuf; ///< Y buffer coordinates + Int_t fNcuts; ///< Number of graphical cuts + Int_t fCutsOpt[kMaxCuts]; ///< Sign of each cut + TCutG *fCuts[kMaxCuts]; ///< Pointers to graphical cuts + TList *fStack; ///< Pointer to stack of histograms (if any) + Int_t fShowProjection; ///< True if a projection must be drawn + TString fShowOption; ///< Option to draw the projection + Int_t fXHighlightBin; ///< X highlight bin + Int_t fYHighlightBin; ///< Y highlight bin + TF3 *fCurrentF3; ///< Current TF3 function private: mutable TString fObjectInfo; diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index b49380546c656..3f6e418186146 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -14,7 +14,6 @@ #include #include #include -#include #include "TROOT.h" #include "TSystem.h" @@ -3198,9 +3197,6 @@ THistPainter::THistPainter() fFunctions = nullptr; fNcuts = 0; fStack = 0; - fLego = nullptr; - fPie = nullptr; - fGraph2DPainter = nullptr; fShowProjection = 0; fShowOption = ""; for (int i=0; iDistancetoPrimitive(px, py); + if (fPie) + return fPie->DistancetoPrimitive(px, py); Double_t x = gPad->AbsPixeltoX(px); Double_t x1 = gPad->AbsPixeltoX(px+1); @@ -3714,10 +3710,8 @@ TList *THistPainter::GetContourList(Double_t contour) const gCurrentHist = fH; - if (!fGraph2DPainter) { - if (dt) ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dt); - else ((THistPainter*)this)->fGraph2DPainter = new TGraph2DPainter(dtOld); - } + if (!fGraph2DPainter) + ((THistPainter*)this)->fGraph2DPainter = dt ? std::make_unique(dt) : std::make_unique(dtOld); return fGraph2DPainter->GetContourList(contour); } @@ -4487,15 +4481,15 @@ void THistPainter::Paint(Option_t *option) if (Hoption.Pie) { if (fH->GetDimension() == 1) { - if (!fPie) fPie = new TPie(fH); + if (!fPie) + fPie = std::make_unique(fH); fPie->Paint(option); } else { Error("Paint", "Option PIE is for 1D histograms only"); } return; } else { - if (fPie) delete fPie; - fPie = nullptr; + fPie.reset(); } fXbuf.resize(kNMAX); @@ -4802,7 +4796,7 @@ void THistPainter::PaintAxis(Bool_t drawGridOnly) Double_t axmax = gPad->GetUxmax(); Double_t aymin = gPad->GetUymin(); Double_t aymax = gPad->GetUymax(); - char *cw = 0; + char *cw = nullptr; TGaxis axis; // In case of option 'cont4' or in case of option 'same' over a 'cont4 plot' @@ -5960,10 +5954,8 @@ void THistPainter::PaintContour(Option_t *option) dt = (TGraphDelaunay2D*)hl->FindObject("TGraphDelaunay2D"); if (!dt) dtOld = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay"); if (!dt && !dtOld) return; - if (!fGraph2DPainter) { - if (dt) fGraph2DPainter = new TGraph2DPainter(dt); - else fGraph2DPainter = new TGraph2DPainter(dtOld); - } + if (!fGraph2DPainter) + fGraph2DPainter = dt ? std::make_unique(dt) : std::make_unique(dtOld); fGraph2DPainter->Paint(option); return; } @@ -6631,7 +6623,7 @@ void THistPainter::Paint2DErrors(Option_t *) fYbuf[1] = Hparam.ymax; fXbuf[2] = Hparam.zmin; fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin()); - fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); + fLego = std::make_unique(fXbuf.data(), fYbuf.data()); TView *view = gPad->GetView(); if (!view) { Error("Paint2DErrors", "no TView in current pad"); @@ -6768,12 +6760,11 @@ void THistPainter::Paint2DErrors(Option_t *) // Paint the Axis if needed if (!Hoption.Axis && !Hoption.Same && !Hoption.Lego && !Hoption.Surf) { - TGaxis *axis = new TGaxis(); - PaintLegoAxis(axis, 90); - delete axis; + TGaxis axis; + PaintLegoAxis(&axis, 90); } - delete fLego; fLego = nullptr; + fLego.reset(); } //////////////////////////////////////////////////////////////////////////////// @@ -7036,9 +7027,11 @@ void THistPainter::PaintH3(Option_t *option) TSeqCollection *ol = view->GetOutline(); if (ol && Hoption.BackBox && Hoption.FrontBox) ol->Paint(option); Hoption.System = kCARTESIAN; - TGaxis *axis = new TGaxis(); - if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90); - delete axis; + + if (!Hoption.Axis && !Hoption.Same) { + TGaxis axis; + PaintLegoAxis(&axis, 90); + } // Draw palette. In case of 4D plot with TTree::Draw() the palette should // be painted with the option colz. @@ -7485,7 +7478,6 @@ void THistPainter::PaintH3Box(Int_t iopt) {0,1,5,4}, {1,2,6,5}, {2,3,7,6}, {3,0,4,7} }; // Define dimensions of world space - TGaxis *axis = new TGaxis(); TAxis *xaxis = fH->GetXaxis(); TAxis *yaxis = fH->GetYaxis(); TAxis *zaxis = fH->GetZaxis(); @@ -7497,7 +7489,7 @@ void THistPainter::PaintH3Box(Int_t iopt) fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst()); fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast()); - fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); + fLego = std::make_unique(fXbuf.data(), fYbuf.data()); // Set view TView *view = gPad->GetView(); @@ -7627,7 +7619,10 @@ void THistPainter::PaintH3Box(Int_t iopt) if (Hoption.FrontBox) fLego->FrontBox(90); // Draw axis and title - if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90); + if (!Hoption.Axis && !Hoption.Same) { + TGaxis axis; + PaintLegoAxis(&axis, 90); + } PaintTitle(); // Draw palette. if needed. @@ -7640,8 +7635,7 @@ void THistPainter::PaintH3Box(Int_t iopt) PaintPalette(); } - delete axis; - delete fLego; fLego = 0; + fLego.reset(); fH->SetFillStyle(fillsav); fH->SetFillColor(colsav); @@ -7668,7 +7662,6 @@ void THistPainter::PaintH3BoxRaster() }; // Define dimensions of world space - TGaxis *axis = new TGaxis(); TAxis *xaxis = fH->GetXaxis(); TAxis *yaxis = fH->GetYaxis(); TAxis *zaxis = fH->GetZaxis(); @@ -7680,7 +7673,7 @@ void THistPainter::PaintH3BoxRaster() fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst()); fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast()); - fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); + fLego = std::make_unique(fXbuf.data(), fYbuf.data()); // Set view TView *view = gPad->GetView(); @@ -7827,11 +7820,13 @@ void THistPainter::PaintH3BoxRaster() if (Hoption.FrontBox) fLego->FrontBox(90); // Draw axis and title - if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90); + if (!Hoption.Axis && !Hoption.Same) { + TGaxis axis; + PaintLegoAxis(&axis, 90); + } PaintTitle(); - delete axis; - delete fLego; fLego = 0; + fLego.reset(); } //////////////////////////////////////////////////////////////////////////////// @@ -7853,7 +7848,6 @@ void THistPainter::PaintH3Iso() Int_t ic2 = ic1+nbcol; Int_t ic3 = ic2+nbcol; - TGaxis *axis = new TGaxis(); TAxis *xaxis = fH->GetXaxis(); TAxis *yaxis = fH->GetYaxis(); TAxis *zaxis = fH->GetZaxis(); @@ -7882,7 +7876,7 @@ void THistPainter::PaintH3Iso() s[1] = 0.5*s[0]; s[2] = 1.5*s[0]; - fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); + fLego = std::make_unique(fXbuf.data(), fYbuf.data()); TView *view = gPad->GetView(); if (!view) { @@ -7941,12 +7935,14 @@ void THistPainter::PaintH3Iso() fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMove2); fLego->FrontBox(90); } - if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90); + if (!Hoption.Axis && !Hoption.Same) { + TGaxis axis; + PaintLegoAxis(&axis, 90); + } PaintTitle(); - delete axis; - delete fLego; fLego = 0; + fLego.reset(); delete [] x; delete [] y; delete [] z; @@ -8014,7 +8010,7 @@ void THistPainter::PaintLego(Option_t *) raster = 0; } - fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data(), Hoption.System); + fLego = std::make_unique(fXbuf.data(), fYbuf.data(), Hoption.System); Int_t nids = -1; TH1 * hid = NULL; @@ -8032,10 +8028,6 @@ void THistPainter::PaintLego(Option_t *) drawShadowsInLego1 = kFALSE; } - // Create axis object - - TGaxis *axis = new TGaxis(); - // Initialize the levels on the Z axis Int_t ndiv = fH->GetContour(); if (ndiv == 0 ) { @@ -8111,7 +8103,7 @@ void THistPainter::PaintLego(Option_t *) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMove1); if (Hoption.BackBox) fLego->BackBox(90); if (Hoption.FrontBox) fLego->FrontBox(90); - if (!Hoption.Axis) PaintLegoAxis(axis, 90); + if (!Hoption.Axis) { TGaxis axis; PaintLegoAxis(&axis, 90); } return; } @@ -8163,10 +8155,12 @@ void THistPainter::PaintLego(Option_t *) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMove2); if (Hoption.FrontBox) fLego->FrontBox(90); } - if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90); + if (!Hoption.Axis && !Hoption.Same) { + TGaxis axis; + PaintLegoAxis(&axis, 90); + } if (Hoption.Zscale) PaintPalette(); - delete axis; - delete fLego; fLego = 0; + fLego.reset(); } //////////////////////////////////////////////////////////////////////////////// @@ -9264,14 +9258,10 @@ void THistPainter::PaintSurface(Option_t *) fYbuf[2] = z2c; } - fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data(), Hoption.System); + fLego = std::make_unique(fXbuf.data(), fYbuf.data(), Hoption.System); fLego->SetEdgeAtt(fH->GetLineColor(),fH->GetLineStyle(),fH->GetLineWidth(),0); fLego->SetFillColor(fH->GetFillColor()); - // Create axis object - - TGaxis *axis = new TGaxis(); - // Initialize the levels on the Z axis Int_t ndiv = fH->GetContour(); if (ndiv == 0 ) { @@ -9436,12 +9426,14 @@ void THistPainter::PaintSurface(Option_t *) fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMove2); if (Hoption.FrontBox) fLego->FrontBox(90); } - if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90); + if (!Hoption.Axis && !Hoption.Same) { + TGaxis axis; + PaintLegoAxis(&axis, 90); + } if (Hoption.Zscale) PaintPalette(); - delete axis; - delete fLego; fLego = 0; + fLego.reset(); } //////////////////////////////////////////////////////////////////////////////// @@ -9460,10 +9452,8 @@ void THistPainter::PaintTriangles(Option_t *option) if (!dt && !dtOld) return; // If needed, create a TGraph2DPainter - if (!fGraph2DPainter) { - if (dt) fGraph2DPainter = new TGraph2DPainter(dt); - else fGraph2DPainter = new TGraph2DPainter(dtOld); - } + if (!fGraph2DPainter) + fGraph2DPainter = dt ? std::make_unique(dt) : std::make_unique(dtOld); // Define the 3D view if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;} @@ -9491,7 +9481,7 @@ void THistPainter::PaintTriangles(Option_t *option) fYbuf[2] = Hparam.zmax; } - fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); + fLego = std::make_unique(fXbuf.data(), fYbuf.data()); TView *view = gPad->GetView(); if (!view) { Error("PaintTriangles", "no TView in current pad"); @@ -9534,14 +9524,13 @@ void THistPainter::PaintTriangles(Option_t *option) // Paint the Axis if needed if (!Hoption.Axis && !Hoption.Same) { - TGaxis *axis = new TGaxis(); - PaintLegoAxis(axis, 90); - delete axis; + TGaxis axis; + PaintLegoAxis(&axis, 90); } if (Hoption.Zscale) PaintPalette(); - delete fLego; fLego = 0; + fLego.reset(); } //////////////////////////////////////////////////////////////////////////////// @@ -10107,7 +10096,6 @@ void THistPainter::PaintTF3() Int_t irep; - TGaxis *axis = new TGaxis(); TAxis *xaxis = fH->GetXaxis(); TAxis *yaxis = fH->GetYaxis(); TAxis *zaxis = fH->GetZaxis(); @@ -10119,7 +10107,7 @@ void THistPainter::PaintTF3() fXbuf[2] = zaxis->GetBinLowEdge(zaxis->GetFirst()); fYbuf[2] = zaxis->GetBinUpEdge(zaxis->GetLast()); - fLego = new TPainter3dAlgorithms(fXbuf.data(), fYbuf.data()); + fLego = std::make_unique(fXbuf.data(), fYbuf.data()); TView *view = gPad->GetView(); if (!view) { @@ -10150,15 +10138,17 @@ void THistPainter::PaintTF3() fLego->SetDrawFace(&TPainter3dAlgorithms::DrawFaceMove2); fLego->FrontBox(90); } - if (!Hoption.Axis && !Hoption.Same) PaintLegoAxis(axis, 90); + if (!Hoption.Axis && !Hoption.Same) { + TGaxis axis; + PaintLegoAxis(&axis, 90); + } PaintTitle(); - delete axis; - delete fLego; fLego = 0; + fLego.reset(); } -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////new TGaxis/////////////////// /// Draw the histogram title /// /// The title is drawn according to the title alignment returned by From 742024466bfe8ef04187601ec78f0f2f932d7cb7 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Fri, 24 Jun 2022 08:52:56 +0200 Subject: [PATCH 022/104] Use std::vectors in histpainter contour plot Ensure that allocated memory always released --- hist/histpainter/src/THistPainter.cxx | 74 +++++++++++---------------- 1 file changed, 29 insertions(+), 45 deletions(-) diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index 3f6e418186146..e563f4b77eb9d 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -5962,10 +5962,10 @@ void THistPainter::PaintContour(Option_t *option) gPad->SetBit(TGraph::kClipFrame); - Double_t *levels = new Double_t[2*kMAXCONTOUR]; - Double_t *xarr = new Double_t[2*kMAXCONTOUR]; - Double_t *yarr = new Double_t[2*kMAXCONTOUR]; - Int_t *itarr = new Int_t[2*kMAXCONTOUR]; + std::vector levels(2*kMAXCONTOUR); + std::vector xarr(2*kMAXCONTOUR); + std::vector yarr(2*kMAXCONTOUR); + std::vector itarr(2*kMAXCONTOUR); Int_t npmax = 0; for (i=0;i<2*kMAXCONTOUR;i++) itarr[i] = 0; @@ -5990,19 +5990,17 @@ void THistPainter::PaintContour(Option_t *option) fH->TAttLine::Modify(); } - TPolyLine **polys = 0; - TPolyLine *poly=0; - TObjArray *contours = 0; - TList *list = 0; - TGraph *graph = 0; - Int_t *np = 0; + std::vector> polys; + TObjArray *contours = nullptr; + TList *list = nullptr; + TGraph *graph = nullptr; + std::vector np; if (Hoption.Contour == 1) { - np = new Int_t[ncontour]; - for (i=0;i(100)); if (Hoption.List == 1) { contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours"); if (contours) { @@ -6049,7 +6047,7 @@ void THistPainter::PaintContour(Option_t *option) else zc[3] = Hparam.zmin; } for (k=0;k<4;k++) { - ir[k] = TMath::BinarySearch(ncontour,levels,zc[k]); + ir[k] = TMath::BinarySearch(ncontour, levels.data(), zc[k]); } if (ir[0] != ir[1] || ir[1] != ir[2] || ir[2] != ir[3] || ir[3] != ir[0]) { x[0] = fXaxis->GetBinCenter(i); @@ -6064,7 +6062,7 @@ void THistPainter::PaintContour(Option_t *option) for (ix=1;ix<=4;ix++) { m = n%4 + 1; ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1], - ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels); + ir[m-1],x[m-1],y[m-1], xarr.data()+lj-1,yarr.data()+lj-1,itarr.data()+lj-1, levels.data()); lj += 2*ljfill; n = m; } @@ -6078,7 +6076,7 @@ void THistPainter::PaintContour(Option_t *option) if (n == 1) m = 4; else m = n-1; ljfill = PaintContourLine(zc[n-1],ir[n-1],x[n-1],y[n-1],zc[m-1], - ir[m-1],x[m-1],y[m-1],&xarr[lj-1],&yarr[lj-1],&itarr[lj-1], levels); + ir[m-1],x[m-1],y[m-1],xarr.data()+lj-1,yarr.data()+lj-1,itarr.data()+lj-1, levels.data()); lj += 2*ljfill; n = m; } @@ -6119,15 +6117,14 @@ void THistPainter::PaintContour(Option_t *option) } if (Hoption.Contour != 1) { fH->TAttLine::Modify(); - gPad->PaintPolyLine(2,&xarr[ix-1],&yarr[ix-1]); + gPad->PaintPolyLine(2,xarr.data()+ix-1,yarr.data()+ix-1); continue; } ipoly = itarr[ix-1]; if (ipoly >=0 && ipoly SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]); - poly->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]); + polys[ipoly]->SetPoint(np[ipoly] ,xarr[ix-1],yarr[ix-1]); + polys[ipoly]->SetPoint(np[ipoly]+1,xarr[ix], yarr[ix]); np[ipoly] += 2; if (npmax < np[ipoly]) npmax = np[ipoly]; } @@ -6137,12 +6134,11 @@ void THistPainter::PaintContour(Option_t *option) } //end of for (j Double_t xmin,ymin; - Double_t *xp, *yp; + std::vector xp, yp; Int_t nadd,iminus,iplus; - Double_t *xx, *yy; Int_t istart; Int_t first = ncontour; - Int_t *polysort = 0; + std::vector polysort; Int_t contListNb; if (Hoption.Contour != 1) goto theEND; @@ -6152,9 +6148,9 @@ void THistPainter::PaintContour(Option_t *option) // in the form of TGraph objects in the ROOT list of special objects. xmin = gPad->GetUxmin(); ymin = gPad->GetUymin(); - xp = new Double_t[2*npmax]; - yp = new Double_t[2*npmax]; - polysort = new Int_t[ncontour]; + xp.resize(2*npmax); + yp.resize(2*npmax); + polysort.resize(ncontour); //find first positive contour for (ipoly=0;ipoly= 0) {first = ipoly; break;} @@ -6171,9 +6167,8 @@ void THistPainter::PaintContour(Option_t *option) if (np[ipoly] == 0) continue; if (Hoption.List) list = (TList*)contours->At(contListNb); contListNb++; - poly = polys[ipoly]; - xx = poly->GetX(); - yy = poly->GetY(); + Double_t *xx = polys[ipoly]->GetX(); + Double_t *yy = polys[ipoly]->GetY(); istart = 0; while (1) { iminus = npmax; @@ -6206,9 +6201,9 @@ void THistPainter::PaintContour(Option_t *option) icol = gStyle->GetColorPalette(theColor); if (ndivz > 1) fH->SetFillColor(icol); fH->TAttFill::Modify(); - gPad->PaintFillArea(iplus-iminus+1,&xp[iminus],&yp[iminus]); + gPad->PaintFillArea(iplus-iminus+1,xp.data()+iminus,yp.data()+iminus); if (Hoption.List) { - graph = new TGraph(iplus-iminus+1,&xp[iminus],&yp[iminus]); + graph = new TGraph(iplus-iminus+1,xp.data()+iminus,yp.data()+iminus); graph->SetFillColor(icol); graph->SetLineWidth(fH->GetLineWidth()); list->Add(graph); @@ -6225,23 +6220,12 @@ void THistPainter::PaintContour(Option_t *option) } } - for (i=0;iResetBit(TGraph::kClipFrame); if (Hoption.Zscale) PaintPalette(); fH->SetLineStyle(linesav); fH->SetLineColor(colorsav); fH->SetFillColor(fillsav); - if (np) delete [] np; - delete [] xarr; - delete [] yarr; - delete [] itarr; - delete [] levels; } //////////////////////////////////////////////////////////////////////////////// From 28bba1ec39e5dbe3b832cc3fe614a419ea94fe9e Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Fri, 24 Jun 2022 09:00:49 +0200 Subject: [PATCH 023/104] Fix memory leak with "cont list" draw option Special "contours" object which is created in with "list" draw option, was not fully deleted when option used again --- hist/histpainter/src/THistPainter.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index e563f4b77eb9d..527d0f210a925 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -6010,6 +6010,8 @@ void THistPainter::PaintContour(Option_t *option) list = (TList*)contours->At(i); if (list) list->Delete(); } + contours->Delete(); + delete contours; } contours = new TObjArray(ncontour); contours->SetName("contours"); From e1ddc19c1922f0de50513ae755e864201e2ea34d Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Fri, 24 Jun 2022 09:21:21 +0200 Subject: [PATCH 024/104] Use std::vector in THistPainter methods instead of plain arrays Ensure that allocated memory released at the end in any circumstances --- hist/histpainter/src/THistPainter.cxx | 53 +++++++++------------------ 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index 527d0f210a925..03496ad107854 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -6316,8 +6316,7 @@ void THistPainter::PaintErrors(Option_t *) static Float_t cxx[30] = {1.0,1.0,0.5,0.5,1.0,1.0,0.5,0.6,1.0,0.5,0.5,1.0,0.5,0.6,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,1.0,1.0,1.0,1.0,0.5,0.5,0.5,1.0}; static Float_t cyy[30] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.5,0.5,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,1.0,1.0,1.0,1.0,0.5,0.5,0.5,1.0}; - Double_t *xline = 0; - Double_t *yline = 0; + std::vector xline, yline; option0 = option1 = option2 = option3 = option4 = optionE = optionEX0 = optionI0 = 0; if (Hoption.Error >= 40) {Hoption.Error -=40; option0 = 1;} if (Int_t(Hoption.Error/10) == 2) {optionEX0 = 1; Hoption.Error -= 10;} @@ -6368,9 +6367,9 @@ void THistPainter::PaintErrors(Option_t *) if (option3) { - xline = new Double_t[2*npoints]; - yline = new Double_t[2*npoints]; - if (!xline || !yline) { + xline.resize(2*npoints); + yline.resize(2*npoints); + if ((npoints > 0) && (xline.empty() || yline.empty())) { Error("PaintErrors", "too many points, out of memory"); return; } @@ -6584,12 +6583,10 @@ void THistPainter::PaintErrors(Option_t *) } npoints = if1-1; } - if (option4) graph.PaintGraph(2*npoints,xline,yline,"FC"); - else graph.PaintGraph(2*npoints,xline,yline,"F"); + if (option4) graph.PaintGraph(2*npoints,xline.data(),yline.data(),"FC"); + else graph.PaintGraph(2*npoints,xline.data(),yline.data(),"F"); gPad->SetLogx(logx); gPad->SetLogy(logy); - delete [] xline; - delete [] yline; } } @@ -6851,13 +6848,12 @@ void THistPainter::PaintHist(Option_t *) last = Hparam.xlast; nbins = last - first + 1; - Double_t *keepx = 0; - Double_t *keepy = 0; + std::vector keepx, keepy; if (fXaxis->GetXbins()->fN) fixbin = 0; else fixbin = 1; - if (fixbin) keepx = new Double_t[2]; - else keepx = new Double_t[nbins+1]; - keepy = new Double_t[nbins]; + if (fixbin) keepx.resize(2); + else keepx.resize(nbins+1); + keepy.resize(nbins); Double_t logymin = 0; if (Hoption.Logy) logymin = TMath::Power(10,ymin); @@ -6948,10 +6944,8 @@ void THistPainter::PaintHist(Option_t *) graph.SetMarkerColor(fH->GetMarkerColor()); if (!Hoption.Same) graph.ResetBit(TGraph::kClipFrame); - graph.PaintGrapHist(nbins, keepx, keepy ,chopth); + graph.PaintGrapHist(nbins, keepx.data(), keepy.data() ,chopth); - delete [] keepx; - delete [] keepy; gStyle->SetBarOffset(baroffsetsave); gStyle->SetBarWidth(barwidthsave); @@ -7842,9 +7836,9 @@ void THistPainter::PaintH3Iso() Int_t ny = fH->GetNbinsY(); Int_t nz = fH->GetNbinsZ(); - Double_t *x = new Double_t[nx]; - Double_t *y = new Double_t[ny]; - Double_t *z = new Double_t[nz]; + std::vector x(nx); + std::vector y(ny); + std::vector z(nz); for (i=0; iGetBinCenter(i+1); for (i=0; iGetBinCenter(i+1); @@ -7867,9 +7861,6 @@ void THistPainter::PaintH3Iso() TView *view = gPad->GetView(); if (!view) { Error("PaintH3Iso", "no TView in current pad"); - delete [] x; - delete [] y; - delete [] z; return; } Double_t thedeg = 90 - gPad->GetTheta(); @@ -7884,9 +7875,6 @@ void THistPainter::PaintH3Iso() Double_t dcol = 0.5/Double_t(nbcol); TColor *colref = gROOT->GetColor(fH->GetFillColor()); if (!colref) { - delete [] x; - delete [] y; - delete [] z; return; } Float_t r, g, b, hue, light, satur; @@ -7914,7 +7902,7 @@ void THistPainter::PaintH3Iso() fmax = ydiff*qa + (yligh1+0.1)*(qd+qs); fLego->SetIsoSurfaceParameters(fmin, fmax, nbcol, ic1, ic2, ic3); - fLego->IsoSurface(1, s, nx, ny, nz, x, y, z, "BF"); + fLego->IsoSurface(1, s, nx, ny, nz, x.data(), y.data(), z.data(), "BF"); if (Hoption.FrontBox) { fLego->InitMoveScreen(-1.1,1.1); @@ -7929,9 +7917,6 @@ void THistPainter::PaintH3Iso() PaintTitle(); fLego.reset(); - delete [] x; - delete [] y; - delete [] z; } //////////////////////////////////////////////////////////////////////////////// @@ -9532,8 +9517,8 @@ void THistPainter::DefineColorLevels(Int_t ndivz) Warning("PaintSurface", "too many color levels, %d >= 100, reset to 99", ndivz); ndivz = 99; } - Double_t *funlevel = new Double_t[ndivz+1]; - Int_t *colorlevel = new Int_t[ndivz+1]; + std::vector funlevel(ndivz+1); + std::vector colorlevel(ndivz+1); Int_t theColor; Int_t ncolors = gStyle->GetNumberOfColors(); for (i = 0; i < ndivz; ++i) { @@ -9542,9 +9527,7 @@ void THistPainter::DefineColorLevels(Int_t ndivz) colorlevel[i] = gStyle->GetColorPalette(theColor); } colorlevel[ndivz] = gStyle->GetColorPalette(ncolors-1); - fLego->ColorFunction(ndivz, funlevel, colorlevel, irep); - delete [] colorlevel; - delete [] funlevel; + fLego->ColorFunction(ndivz, funlevel.data(), colorlevel.data(), irep); } //////////////////////////////////////////////////////////////////////////////// From de4a1b38dfdf06a1ba294acacfe06d35ed4d6d94 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Fri, 24 Jun 2022 09:49:59 +0200 Subject: [PATCH 025/104] [histpainter] use nullptr, avoid Form(), simplify TIter loops Also avoid comparation obj->TestBit(bit) == 0 or == 1, just use in logical operators --- hist/histpainter/src/THistPainter.cxx | 104 ++++++++++++-------------- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index 03496ad107854..6d69242114033 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -3445,8 +3445,8 @@ void THistPainter::DrawPanel() } TVirtualPadEditor *editor = TVirtualPadEditor::GetPadEditor(); editor->Show(); - gROOT->ProcessLine(Form("((TCanvas*)0x%zx)->Selected((TVirtualPad*)0x%zx,(TObject*)0x%zx,1)", - (size_t)gPad->GetCanvas(), (size_t)gPad, (size_t)fH)); + gROOT->ProcessLine(TString::Format("((TCanvas*)0x%zx)->Selected((TVirtualPad*)0x%zx,(TObject*)0x%zx,1)", + (size_t)gPad->GetCanvas(), (size_t)gPad, (size_t)fH).Data()); } //////////////////////////////////////////////////////////////////////////////// @@ -3477,7 +3477,7 @@ void THistPainter::ExecuteEvent(Int_t event, Int_t px, Int_t py) // come here if we have a lego/surface in the pad TView *view = gPad->GetView(); - if (!fShowProjection && view && view->TestBit(kCannotRotate) == 0) { + if (!fShowProjection && view && !view->TestBit(kCannotRotate)) { view->ExecuteRotateView(event, px, py); return; } @@ -4469,8 +4469,8 @@ void THistPainter::Paint(Option_t *option) if (Hoption.Spec) { if (!TableInit()) return; if (!TClass::GetClass("TSpectrum2Painter")) gSystem->Load("libSpectrumPainter"); - gROOT->ProcessLineFast(Form("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%zx,\"%s\",%d)", - (size_t)fH, option, Hoption.Spec)); + gROOT->ProcessLineFast(TString::Format("TSpectrum2Painter::PaintSpectrum((TH2F*)0x%zx,\"%s\",%d)", + (size_t)fH, option, Hoption.Spec).Data()); return; } @@ -4514,7 +4514,7 @@ void THistPainter::Paint(Option_t *option) if (view) { if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri) { delete view; - gPad->SetView(0); + gPad->SetView(nullptr); } } if (fH->GetDimension() > 1 || Hoption.Lego || Hoption.Surf) { @@ -4678,7 +4678,7 @@ void THistPainter::PaintArrows(Option_t *) fH->SetContour(ndiv); } ndivz = TMath::Abs(ndiv); - if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv); + if (!fH->TestBit(TH1::kUserContour)) fH->SetContour(ndiv); scale = ndivz/(fH->GetMaximum()-fH->GetMinimum()); } @@ -4757,8 +4757,8 @@ void THistPainter::PaintAxis(Bool_t drawGridOnly) // Repainting alphanumeric labels axis on a plot done with // the option HBAR (horizontal) needs some adjustments. - TAxis *xaxis = 0; - TAxis *yaxis = 0; + TAxis *xaxis = nullptr; + TAxis *yaxis = nullptr; if (Hoption.Same && Hoption.Axis) { // Axis repainted (TPad::RedrawAxis) if (fXaxis->GetLabels() || fYaxis->GetLabels()) { // One axis has alphanumeric labels TIter next(gPad->GetListOfPrimitives()); @@ -5132,10 +5132,10 @@ void THistPainter::PaintBarH(Option_t *) // Draw box with histogram statistics and/or fit parameters if ((Hoption.Same%10) != 1 && !fH->TestBit(TH1::kNoStats)) { // bit set via TH1::SetStats TIter next(fFunctions); - TObject *obj = 0; + TObject *obj = nullptr; while ((obj = next())) { if (obj->InheritsFrom(TF1::Class())) break; - obj = 0; + obj = nullptr; } PaintStat(gStyle->GetOptStat(),(TF1*)obj); } @@ -5613,7 +5613,7 @@ void THistPainter::PaintColorLevelsFast(Option_t*) } std::vector colorBounds(ndiv); std::vector contours(ndiv, 0); - if (fH->TestBit(TH1::kUserContour) == 0) { + if (!fH->TestBit(TH1::kUserContour)) { fH->SetContour(ndiv); } else { fH->GetContour(contours.data()); @@ -5664,7 +5664,7 @@ void THistPainter::PaintColorLevelsFast(Option_t*) if (z > zmax) z = zmax; if (z < zmin) z = zmin; - if (fH->TestBit(TH1::kUserContour) == 1) { + if (fH->TestBit(TH1::kUserContour)) { // contours are absolute values auto index = TMath::BinarySearch(contours.size(), contours.data(), z); z = colorBounds[index]; @@ -5806,7 +5806,7 @@ void THistPainter::PaintColorLevels(Option_t*) fH->SetContour(ndiv); } Int_t ndivz = TMath::Abs(ndiv); - if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv); + if (!fH->TestBit(TH1::kUserContour)) fH->SetContour(ndiv); Double_t scale = (dz ? ndivz / dz : 1.0); Int_t color; @@ -5980,7 +5980,7 @@ void THistPainter::PaintContour(Option_t *option) kMAXCONTOUR, ncontour); ncontour = kMAXCONTOUR-1; } - if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ncontour); + if (!fH->TestBit(TH1::kUserContour)) fH->SetContour(ncontour); for (i=0;iGetContourLevelPad(i); Int_t linesav = fH->GetLineStyle(); @@ -6786,7 +6786,7 @@ void THistPainter::PaintFunction(Option_t *) obj = lnk->GetObject(); TVirtualPad *padsave = gPad; if (obj->InheritsFrom(TF2::Class())) { - if (obj->TestBit(TF2::kNotDraw) == 0) { + if (!obj->TestBit(TF2::kNotDraw)) { if (Hoption.Lego || Hoption.Surf || Hoption.Error >= 100) { TF2 *f2 = (TF2*)obj; f2->SetMinimum(fH->GetMinimum()); @@ -6798,7 +6798,7 @@ void THistPainter::PaintFunction(Option_t *) } } } else if (obj->InheritsFrom(TF1::Class())) { - if (obj->TestBit(TF1::kNotDraw) == 0) obj->Paint("lsame"); + if (!obj->TestBit(TF1::kNotDraw)) obj->Paint("lsame"); } else { //Let's make this 'function' selectable on iOS device (for example, it can be TPaveStat). gPad->PushSelectableObject(obj); @@ -6958,7 +6958,7 @@ void THistPainter::PaintHist(Option_t *) void THistPainter::PaintH3(Option_t *option) { - char *cmd; + TString cmd; TString opt = option; opt.ToLower(); Int_t irep; @@ -6984,7 +6984,7 @@ void THistPainter::PaintH3(Option_t *option) PaintTF3(); return; } else { - cmd = Form("TPolyMarker3D::PaintH3((TH1 *)0x%zx,\"%s\");",(size_t)fH,option); + cmd.Form("TPolyMarker3D::PaintH3((TH1 *)0x%zx,\"%s\");",(size_t)fH,option); } if (strstr(opt,"fb")) Hoption.FrontBox = 0; @@ -6998,7 +6998,7 @@ void THistPainter::PaintH3(Option_t *option) view->SetView(phideg, thedeg, psideg, irep); // Paint the data - gROOT->ProcessLine(cmd); + gROOT->ProcessLine(cmd.Data()); if (Hoption.Same) return; @@ -7028,10 +7028,9 @@ void THistPainter::PaintH3(Option_t *option) PaintTitle(); //Draw stats and fit results - TF1 *fit = 0; + TF1 *fit = nullptr; TIter next(fFunctions); - TObject *obj; - while ((obj = next())) { + while (auto obj = next()) { if (obj->InheritsFrom(TF1::Class())) { fit = (TF1*)obj; break; @@ -8006,7 +8005,7 @@ void THistPainter::PaintLego(Option_t *) fH->SetContour(ndiv); } Int_t ndivz = TMath::Abs(ndiv); - if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv); + if (!fH->TestBit(TH1::kUserContour)) fH->SetContour(ndiv); // Initialize colors if (!fStack) { @@ -8323,19 +8322,18 @@ void THistPainter::PaintLegoAxis(TGaxis *axis, Double_t ang) void THistPainter::PaintPalette() { - TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette"); TView *view = gPad->GetView(); if (palette) { if (view) { if (!palette->TestBit(TPaletteAxis::kHasView)) { fFunctions->Remove(palette); - delete palette; palette = 0; + delete palette; palette = nullptr; } } else { if (palette->TestBit(TPaletteAxis::kHasView)) { fFunctions->Remove(palette); - delete palette; palette = 0; + delete palette; palette = nullptr; } } // make sure the histogram member of the palette is setup correctly. It may not be after a Clone() @@ -8516,13 +8514,11 @@ void THistPainter::PaintSpecialObjects(const TObject *obj, Option_t *option) void THistPainter::PaintStat(Int_t dostat, TF1 *fit) { - TString tt, tf; Int_t dofit; - TPaveStats *stats = 0; + TPaveStats *stats = nullptr; TIter next(fFunctions); - TObject *obj; - while ((obj = next())) { + while (auto obj = next()) { if (obj->InheritsFrom(TPaveStats::Class())) { stats = (TPaveStats*)obj; break; @@ -8739,10 +8735,9 @@ void THistPainter::PaintStat2(Int_t dostat, TF1 *fit) TString tt, tf; Int_t dofit; - TPaveStats *stats = 0; + TPaveStats *stats = nullptr; TIter next(fFunctions); - TObject *obj; - while ((obj = next())) { + while (auto obj = next()) { if (obj->InheritsFrom(TPaveStats::Class())) { stats = (TPaveStats*)obj; break; @@ -8956,10 +8951,9 @@ void THistPainter::PaintStat3(Int_t dostat, TF1 *fit) TString tt, tf; Int_t dofit; - TPaveStats *stats = 0; + TPaveStats *stats = nullptr; TIter next(fFunctions); - TObject *obj; - while ((obj = next())) { + while (auto obj = next()) { if (obj->InheritsFrom(TPaveStats::Class())) { stats = (TPaveStats*)obj; break; @@ -9240,7 +9234,7 @@ void THistPainter::PaintSurface(Option_t *) fH->SetContour(ndiv); } Int_t ndivz = TMath::Abs(ndiv); - if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv); + if (!fH->TestBit(TH1::kUserContour)) fH->SetContour(ndiv); if (Hoption.Surf == 13 || Hoption.Surf == 15) fLego->SetMesh(3); if (Hoption.Surf == 12 || Hoption.Surf == 14 || Hoption.Surf == 17) fLego->SetMesh(0); @@ -9593,10 +9587,9 @@ void THistPainter::PaintTable(Option_t *option) if (!Hoption.Lego && !Hoption.Surf && !Hoption.Tri && !(Hoption.Error >= 100)) PaintAxis(kFALSE); - TF1 *fit = 0; + TF1 *fit = nullptr; TIter next(fFunctions); - TObject *obj; - while ((obj = next())) { + while (auto obj = next()) { if (obj->InheritsFrom(TF1::Class())) { fit = (TF1*)obj; break; @@ -9726,17 +9719,14 @@ void THistPainter::PaintTH2PolyColorLevels(Option_t *) fH->SetContour(ndiv); } Int_t ndivz = TMath::Abs(ndiv); - if (fH->TestBit(TH1::kUserContour) == 0) fH->SetContour(ndiv); + if (!fH->TestBit(TH1::kUserContour)) fH->SetContour(ndiv); Double_t scale = ndivz/dz; - TH2PolyBin *b; - TIter next(((TH2Poly*)fH)->GetBins()); - TObject *obj, *poly; - while ((obj=next())) { - b = (TH2PolyBin*)obj; - poly = b->GetPolygon(); + while (auto obj = next()) { + TH2PolyBin *b = (TH2PolyBin*)obj; + TObject *poly = b->GetPolygon(); z = b->GetContent(); if (z==0 && Hoption.Zero) continue; @@ -10140,13 +10130,13 @@ void THistPainter::PaintTitle() if (Hoption.Same) return; if (fH->TestBit(TH1::kNoTitle)) return; Int_t nt = strlen(fH->GetTitle()); - TPaveText *title = 0; + TPaveText *title = nullptr; TObject *obj; TIter next(gPad->GetListOfPrimitives()); while ((obj = next())) { if (!obj->InheritsFrom(TPaveText::Class())) continue; title = (TPaveText*)obj; - if (strcmp(title->GetName(),"title")) {title = 0; continue;} + if (strcmp(title->GetName(),"title")) {title = nullptr; continue;} break; } if (nt == 0 || gStyle->GetOptTitle() <= 0) { @@ -10683,7 +10673,7 @@ void THistPainter::SetShowProjection(const char *option,Int_t nbins) else fShowOption = option+2; fShowProjection = projection+100*nbins; gROOT->MakeDefCanvas(); - gPad->SetName(Form("c_%zx_projection_%d", (size_t)fH, fShowProjection)); + gPad->SetName(TString::Format("c_%zx_projection_%d", (size_t)fH, fShowProjection).Data()); gPad->SetGrid(); } @@ -10718,8 +10708,8 @@ void THistPainter::ShowProjectionX(Int_t /*px*/, Int_t py) // Create or set the new canvas proj x TVirtualPad *padsav = gPad; - TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%zx_projection_%d", - (size_t)fH, fShowProjection)); + TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(TString::Format("c_%zx_projection_%d", + (size_t)fH, fShowProjection).Data()); if (c) { c->Clear(); } else { @@ -10801,8 +10791,8 @@ void THistPainter::ShowProjectionY(Int_t px, Int_t /*py*/) // Create or set the new canvas proj y TVirtualPad *padsav = gPad; - TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%zx_projection_%d", - (size_t)fH, fShowProjection)); + TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(TString::Format("c_%zx_projection_%d", + (size_t)fH, fShowProjection).Data()); if (c) { c->Clear(); } else { @@ -10905,8 +10895,8 @@ void THistPainter::ShowProjection3(Int_t px, Int_t py) Double_t cx = (pxmax-pxmin)/(uxmax-uxmin); Double_t cy = (pymax-pymin)/(uymax-uymin); TVirtualPad *padsav = gPad; - TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(Form("c_%zx_projection_%d", - (size_t)fH, fShowProjection)); + TVirtualPad *c = (TVirtualPad*)gROOT->GetListOfCanvases()->FindObject(TString::Format("c_%zx_projection_%d", + (size_t)fH, fShowProjection).Data()); if (!c) { fShowProjection = 0; return; From 011a98d7e887f24788e71d4b67fdaca869c5e3b8 Mon Sep 17 00:00:00 2001 From: Enrico Guiraud Date: Wed, 22 Jun 2022 16:40:24 +0200 Subject: [PATCH 026/104] [NFC][DF] Fix typo in Python example Inline C++ needs double quotes, Python is ok with single quotes. --- tree/dataframe/inc/ROOT/RDF/RInterface.hxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tree/dataframe/inc/ROOT/RDF/RInterface.hxx b/tree/dataframe/inc/ROOT/RDF/RInterface.hxx index 00deffd0ef490..f9c2cf96d1d56 100644 --- a/tree/dataframe/inc/ROOT/RDF/RInterface.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RInterface.hxx @@ -647,8 +647,8 @@ public: /// /// ### Example usage: /// ~~~{.py} - /// df = ROOT.RDataFrame("mytree", ["sample1.root","sample2.root"]) - /// df.DefinePerSample("weightbysample", "rdfsampleinfo_.Contains('sample1') ? 1.0f : 2.0f") + /// df = ROOT.RDataFrame('mytree', ['sample1.root','sample2.root']) + /// df.DefinePerSample('weightbysample', 'rdfsampleinfo_.Contains("sample1") ? 1.0f : 2.0f') /// ~~~ /// /// \note From 45d1530f462b064c13ebb3f3c9c5f266f35a3301 Mon Sep 17 00:00:00 2001 From: Enrico Guiraud Date: Wed, 22 Jun 2022 18:30:43 +0200 Subject: [PATCH 027/104] [DF] Remove redundant calls to RDefine::InitSlot We now register all RDefine nodes, incuding varied defines, with RLoopManager, which is in charge of calling InitSlot on all registered nodes, so we do not need to propagate the InitSlot call from RVariation or RDefine to other RDefines. --- tree/dataframe/inc/ROOT/RDF/RDefine.hxx | 3 --- tree/dataframe/inc/ROOT/RDF/RVariation.hxx | 2 -- 2 files changed, 5 deletions(-) diff --git a/tree/dataframe/inc/ROOT/RDF/RDefine.hxx b/tree/dataframe/inc/ROOT/RDF/RDefine.hxx index 8ce8891327da1..9ba4b0f60e2b4 100644 --- a/tree/dataframe/inc/ROOT/RDF/RDefine.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RDefine.hxx @@ -121,9 +121,6 @@ public: fLoopManager->GetDataSource()}; fValues[slot] = RDFInternal::MakeColumnReaders(slot, r, ColumnTypes_t{}, info, fVariation); fLastCheckedEntry[slot * RDFInternal::CacheLineStep()] = -1; - - for (auto &e : fVariedDefines) - e.second->InitSlot(r, slot); } /// Return the (type-erased) address of the Define'd value for the given processing slot. diff --git a/tree/dataframe/inc/ROOT/RDF/RVariation.hxx b/tree/dataframe/inc/ROOT/RDF/RVariation.hxx index 20bca0f699e8b..a326340a7fbc3 100644 --- a/tree/dataframe/inc/ROOT/RDF/RVariation.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RVariation.hxx @@ -212,8 +212,6 @@ public: void InitSlot(TTreeReader *r, unsigned int slot) final { - for (auto &define : fColumnRegister.GetDefines()) - define.second->InitSlot(r, slot); RColumnReadersInfo info{fInputColumns, fColumnRegister, fIsDefine.data(), fLoopManager->GetDSValuePtrs(), fLoopManager->GetDataSource()}; fValues[slot] = MakeColumnReaders(slot, r, ColumnTypes_t{}, info); From 9c440e54d3da9e4562c8460baeed95496bf56ded Mon Sep 17 00:00:00 2001 From: Enrico Guiraud Date: Wed, 22 Jun 2022 18:34:58 +0200 Subject: [PATCH 028/104] [NFC][DF] Consistently use the imperative mood in docs --- tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx b/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx index 685cc35a4e1b8..7d95a1b1e4f9a 100644 --- a/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx @@ -83,15 +83,15 @@ public: ~RColumnRegister(); //////////////////////////////////////////////////////////////////////////// - /// \brief Returns the list of the names of the defined columns (Defines + Aliases). + /// \brief Return the list of the names of the defined columns (Defines + Aliases). ColumnNames_t GetNames() const { return *fColumnNames; } //////////////////////////////////////////////////////////////////////////// - /// \brief Returns a map of pointers to the defined columns. + /// \brief Return a map of pointers to the defined columns. const DefinesMap_t &GetDefines() const { return *fDefines; } //////////////////////////////////////////////////////////////////////////// - /// \brief Returns the multimap of systematic variations, see fVariations. + /// \brief Return the multimap of systematic variations, see fVariations. const VariationsMap_t &GetVariations() const { return *fVariations; } //////////////////////////////////////////////////////////////////////////// From 0190901e830d2f223ad5e0e6dc77b2d981f5f539 Mon Sep 17 00:00:00 2001 From: Enrico Guiraud Date: Wed, 22 Jun 2022 18:38:59 +0200 Subject: [PATCH 029/104] [NFC][DF] Remove redundant `private:` --- tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx b/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx index 7d95a1b1e4f9a..5be1989e957b7 100644 --- a/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx @@ -46,15 +46,6 @@ class RColumnRegister { /// See fVariations for more information on this type. using VariationsMap_t = std::unordered_multimap>; - //////////////////////////////////////////////////////////////////////////// - /// \brief Add a new name to the list returned by `GetNames` without booking a new column. - /// - /// This is needed because we abuse fColumnNames to also keep track of the aliases defined - /// in each branch of the computation graph. - /// Internally it recreates the vector with the new name, and swaps it with the old one. - void AddName(std::string_view name); - -private: std::shared_ptr fLoopManager; /// Immutable map of Defines, can be shared among several nodes. @@ -69,6 +60,14 @@ private: std::shared_ptr fVariations; std::shared_ptr fColumnNames; ///< Names of Defines and Aliases registered so far. + //////////////////////////////////////////////////////////////////////////// + /// \brief Add a new name to the list returned by `GetNames` without booking a new column. + /// + /// This is needed because we abuse fColumnNames to also keep track of the aliases defined + /// in each branch of the computation graph. + /// Internally it recreates the vector with the new name, and swaps it with the old one. + void AddName(std::string_view name); + public: RColumnRegister(const RColumnRegister &) = default; RColumnRegister(RColumnRegister &&) = default; From 09e59159f2b4f65b631210c6ad88dbdfded68dfc Mon Sep 17 00:00:00 2001 From: Enrico Guiraud Date: Wed, 22 Jun 2022 18:48:36 +0200 Subject: [PATCH 030/104] [NFC][DF] Move docstrings to source file As per ROOT conventions. --- .../inc/ROOT/RDF/RColumnRegister.hxx | 34 ------------------ tree/dataframe/src/RDFColumnRegister.cxx | 35 +++++++++++++++++++ 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx b/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx index 5be1989e957b7..d55f09c6c6d76 100644 --- a/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx @@ -60,12 +60,6 @@ class RColumnRegister { std::shared_ptr fVariations; std::shared_ptr fColumnNames; ///< Names of Defines and Aliases registered so far. - //////////////////////////////////////////////////////////////////////////// - /// \brief Add a new name to the list returned by `GetNames` without booking a new column. - /// - /// This is needed because we abuse fColumnNames to also keep track of the aliases defined - /// in each branch of the computation graph. - /// Internally it recreates the vector with the new name, and swaps it with the old one. void AddName(std::string_view name); public: @@ -93,52 +87,24 @@ public: /// \brief Return the multimap of systematic variations, see fVariations. const VariationsMap_t &GetVariations() const { return *fVariations; } - //////////////////////////////////////////////////////////////////////////// - /// \brief Check if the provided name is tracked in the names list bool IsDefineOrAlias(std::string_view name) const; - //////////////////////////////////////////////////////////////////////////// - /// \brief Add a new defined column. - /// Internally it recreates the map with the new column, and swaps it with the old one. void AddDefine(const std::shared_ptr &column); - /// \brief Add a new alias to the ledger. void AddAlias(std::string_view alias, std::string_view colName); - //////////////////////////////////////////////////////////////////////////// - /// \brief Return true if the given column name is an existing alias. bool IsAlias(const std::string &name) const; - //////////////////////////////////////////////////////////////////////////// - /// \brief Return the actual column name that the alias resolves to. - /// Drills through multiple levels of aliasing if needed. - /// Returns the input in case it's not an alias. - /// Expands `#%var` to `R_rdf_sizeof_var` (the #%var columns are implicitly-defined aliases). std::string ResolveAlias(std::string_view alias) const; - /// \brief Register a new systematic variation. void AddVariation(const std::shared_ptr &variation); - //////////////////////////////////////////////////////////////////////////// - /// \brief Get the names of the variations that directly provide alternative values for this column. std::vector GetVariationsFor(const std::string &column) const; - //////////////////////////////////////////////////////////////////////////// - /// \brief Get the names of all variations that directly or indirectly affect a given column. - /// - /// This list includes variations applied to the column as well as variations applied to other - /// columns on which the value of this column depends (typically via a Define expression). std::vector GetVariationDeps(const std::string &column) const; - //////////////////////////////////////////////////////////////////////////// - /// \brief Get the names of all variations that directly or indirectly affect the specified columns. - /// - /// This list includes variations applied to the columns as well as variations applied to other - /// columns on which the value of any of these columns depend (typically via Define expressions). std::vector GetVariationDeps(const ColumnNames_t &columns) const; - //////////////////////////////////////////////////////////////////////////// - /// \brief Return the RVariation object that handles the specified variation of the specified column. RVariationBase &FindVariation(const std::string &colName, const std::string &variationName) const; }; diff --git a/tree/dataframe/src/RDFColumnRegister.cxx b/tree/dataframe/src/RDFColumnRegister.cxx index 8c0a2707108bd..3e7bf7f49b72b 100644 --- a/tree/dataframe/src/RDFColumnRegister.cxx +++ b/tree/dataframe/src/RDFColumnRegister.cxx @@ -30,12 +30,17 @@ RColumnRegister::~RColumnRegister() fColumnNames.reset(); } +//////////////////////////////////////////////////////////////////////////// +/// \brief Check if the provided name is tracked in the names list bool RColumnRegister::IsDefineOrAlias(std::string_view name) const { const auto ccolnamesEnd = fColumnNames->end(); return ccolnamesEnd != std::find(fColumnNames->begin(), ccolnamesEnd, name); } +//////////////////////////////////////////////////////////////////////////// +/// \brief Add a new defined column. +/// Internally it recreates the map with the new column, and swaps it with the old one. void RColumnRegister::AddDefine(const std::shared_ptr &column) { auto newDefines = std::make_shared(*fDefines); @@ -45,6 +50,8 @@ void RColumnRegister::AddDefine(const std::shared_ptr &c AddName(colName); } +//////////////////////////////////////////////////////////////////////////// +/// \brief Register a new systematic variation. void RColumnRegister::AddVariation(const std::shared_ptr &variation) { auto newVariations = std::make_shared(*fVariations); @@ -54,6 +61,8 @@ void RColumnRegister::AddVariation(const std::shared_ptr &variat fVariations = std::move(newVariations); } +//////////////////////////////////////////////////////////////////////////// +/// \brief Get the names of the variations that directly provide alternative values for this column. std::vector RColumnRegister::GetVariationsFor(const std::string &column) const { std::vector variations; @@ -65,11 +74,21 @@ std::vector RColumnRegister::GetVariationsFor(const std::string &co return variations; } +//////////////////////////////////////////////////////////////////////////// +/// \brief Get the names of all variations that directly or indirectly affect a given column. +/// +/// This list includes variations applied to the column as well as variations applied to other +/// columns on which the value of this column depends (typically via a Define expression). std::vector RColumnRegister::GetVariationDeps(const std::string &column) const { return GetVariationDeps(std::vector{column}); } +//////////////////////////////////////////////////////////////////////////// +/// \brief Get the names of all variations that directly or indirectly affect the specified columns. +/// +/// This list includes variations applied to the columns as well as variations applied to other +/// columns on which the value of any of these columns depend (typically via Define expressions). std::vector RColumnRegister::GetVariationDeps(const ColumnNames_t &columns) const { // here we assume that columns do not contain aliases, they must have already been resolved @@ -91,6 +110,7 @@ std::vector RColumnRegister::GetVariationDeps(const ColumnNames_t & return {variationNames.begin(), variationNames.end()}; } +//////////////////////////////////////////////////////////////////////////// /// \brief Return the RVariation object that handles the specified variation of the specified column. RVariationBase &RColumnRegister::FindVariation(const std::string &colName, const std::string &variationName) const { @@ -103,6 +123,12 @@ RVariationBase &RColumnRegister::FindVariation(const std::string &colName, const return *it->second; } +//////////////////////////////////////////////////////////////////////////// +/// \brief Add a new name to the list returned by `GetNames` without booking a new column. +/// +/// This is needed because we abuse fColumnNames to also keep track of the aliases defined +/// in each branch of the computation graph. +/// Internally it recreates the vector with the new name, and swaps it with the old one. void RColumnRegister::AddName(std::string_view name) { const auto &names = *fColumnNames; @@ -114,6 +140,8 @@ void RColumnRegister::AddName(std::string_view name) fColumnNames = newColsNames; } +//////////////////////////////////////////////////////////////////////////// +/// \brief Add a new alias to the ledger. void RColumnRegister::AddAlias(std::string_view alias, std::string_view colName) { // at this point validation of alias and colName has already happened, we trust that @@ -124,11 +152,18 @@ void RColumnRegister::AddAlias(std::string_view alias, std::string_view colName) AddName(alias); } +//////////////////////////////////////////////////////////////////////////// +/// \brief Return true if the given column name is an existing alias. bool RColumnRegister::IsAlias(const std::string &name) const { return fAliases->find(name) != fAliases->end(); } +//////////////////////////////////////////////////////////////////////////// +/// \brief Return the actual column name that the alias resolves to. +/// Drills through multiple levels of aliasing if needed. +/// Returns the input in case it's not an alias. +/// Expands `#%var` to `R_rdf_sizeof_var` (the #%var columns are implicitly-defined aliases). std::string RColumnRegister::ResolveAlias(std::string_view alias) const { std::string aliasStr{alias}; From 674258c0b3f5715654ca04297569206a94fe714c Mon Sep 17 00:00:00 2001 From: Carsten Burgard Date: Mon, 27 Jun 2022 15:34:29 +0200 Subject: [PATCH 031/104] bugfix to use HF-internal observables instead of dataset-internal ones --- roofit/hs3/src/JSONFactories_HistFactory.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roofit/hs3/src/JSONFactories_HistFactory.cxx b/roofit/hs3/src/JSONFactories_HistFactory.cxx index 978e7c1fdc0a1..43cf4e825797c 100644 --- a/roofit/hs3/src/JSONFactories_HistFactory.cxx +++ b/roofit/hs3/src/JSONFactories_HistFactory.cxx @@ -85,7 +85,7 @@ std::vector getVarnames(const RooHistFunc *hf) std::unique_ptr histFunc2TH1(const RooHistFunc *hf) { const RooDataHist &dh = hf->dataHist(); - RooArgList vars(*dh.get()); + RooArgList vars(*hf->getVariables()); auto varnames = RooJSONFactoryWSTool::names(&vars); std::unique_ptr hist{hf->createHistogram(RooJSONFactoryWSTool::concat(&vars).c_str())}; hist->SetDirectory(nullptr); From e9fa243af91217e9b108d828009c81ccba7666b5 Mon Sep 17 00:00:00 2001 From: Carsten Burgard Date: Mon, 27 Jun 2022 15:34:41 +0200 Subject: [PATCH 032/104] adding new classes to exporters and importers --- etc/RooFitHS3_wsexportkeys.json | 28 ++++++++++++++++++++++++- etc/RooFitHS3_wsfactoryexpressions.json | 26 +++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/etc/RooFitHS3_wsexportkeys.json b/etc/RooFitHS3_wsexportkeys.json index b2850905e5e0c..55bd8d41fdd29 100644 --- a/etc/RooFitHS3_wsexportkeys.json +++ b/etc/RooFitHS3_wsexportkeys.json @@ -54,7 +54,14 @@ "proxies": { "set": "summands" } - }, + }, + "RooBernstein": { + "type": "BernsteinPolynomial", + "proxies": { + "coefList": "coefficients", + "x": "x" + } + }, "RooArgusBG": { "type": "ARGUS", "proxies": { @@ -63,5 +70,24 @@ "c": "slope", "p": "power" } + }, + "RooCBShape": { + "type": "CrystalBallShape", + "proxies": { + "alpha": "alpha", + "m": "m", + "m0": "m0", + "n": "n", + "sigma": "sigma" + } + }, + "RooBifurGauss": { + "type": "BifurkatedGaussian", + "proxies": { + "x": "x", + "mean": "mean", + "sigmaL": "sigmaL", + "sigmaR": "sigmaR" + } } } diff --git a/etc/RooFitHS3_wsfactoryexpressions.json b/etc/RooFitHS3_wsfactoryexpressions.json index 309b340a3f1f0..32830a46295cb 100644 --- a/etc/RooFitHS3_wsfactoryexpressions.json +++ b/etc/RooFitHS3_wsfactoryexpressions.json @@ -57,5 +57,31 @@ "slope", "power" ] + }, + "BernsteinPolynomial": { + "class": "RooBernstein", + "arguments": [ + "x", + "coefficients" + ] + }, + "CrystalBallShape": { + "class": "RooCBShape", + "arguments": [ + "m", + "m0", + "sigma", + "alpha", + "n" + ] + }, + "BifurkatedGaussian": { + "class": "RooBifurGauss", + "arguments": [ + "x", + "mean", + "sigmaL", + "sigmaR" + ] } } From 943d31dfe1a41948ccfc5901fbcacaa8579712bd Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 23 Jun 2022 13:03:22 +0200 Subject: [PATCH 033/104] [cmake] set minimal nlohmann/json version to 3.9 Avoid potential problems with other older nlohmann version like 3.6 --- cmake/modules/SearchInstalledSoftware.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/SearchInstalledSoftware.cmake b/cmake/modules/SearchInstalledSoftware.cmake index 176eb99b5cfaf..29a2e852b57b5 100644 --- a/cmake/modules/SearchInstalledSoftware.cmake +++ b/cmake/modules/SearchInstalledSoftware.cmake @@ -72,7 +72,7 @@ if(NOT builtin_nlohmannjson) if(fail-on-missing) find_package(nlohmann_json REQUIRED) else() - find_package(nlohmann_json QUIET) + find_package(nlohmann_json 3.9 QUIET) if(nlohmann_json_FOUND) get_target_property(_nlohmann_json_incl nlohmann_json::nlohmann_json INTERFACE_INCLUDE_DIRECTORIES) message(STATUS "Found nlohmann/json.hpp in ${_nlohmann_json_incl} (found version ${nlohmann_json_VERSION})") From c4cf25b3ae7ba0be3cd02b190d4324bfcf72dd02 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Mon, 27 Jun 2022 14:10:21 +0200 Subject: [PATCH 034/104] Use std::vector for dynamic arrays in 3d algorithms Ensure correct cleanup of arrays in any case --- hist/histpainter/src/TPainter3dAlgorithms.cxx | 211 +++++------------- hist/histpainter/src/TPainter3dAlgorithms.h | 64 +++--- 2 files changed, 89 insertions(+), 186 deletions(-) diff --git a/hist/histpainter/src/TPainter3dAlgorithms.cxx b/hist/histpainter/src/TPainter3dAlgorithms.cxx index 487a7997bb50a..24cf5d929879f 100644 --- a/hist/histpainter/src/TPainter3dAlgorithms.cxx +++ b/hist/histpainter/src/TPainter3dAlgorithms.cxx @@ -51,16 +51,6 @@ const Int_t kF3FillColor1 = 201; const Int_t kF3FillColor2 = 202; const Int_t kF3LineColor = 203; -// Static arrays used to paint stacked lego plots. -const Int_t kVSizeMax = 20; -static Double_t gV[kVSizeMax]; -static Double_t gTT[4*kVSizeMax]; -static Int_t gColorMain[kVSizeMax+1]; -static Int_t gColorDark[kVSizeMax+1]; -static Int_t gEdgeColor[kVSizeMax+1]; -static Int_t gEdgeStyle[kVSizeMax+1]; -static Int_t gEdgeWidth[kVSizeMax+1]; - extern TH1 *gCurrentHist; //these 3 globals should be replaced by class members extern Hoption_t Hoption; extern Hparam_t Hparam; @@ -71,11 +61,9 @@ extern Hparam_t Hparam; TPainter3dAlgorithms::TPainter3dAlgorithms(): TAttLine(1,1,1), TAttFill(1,0) { Int_t i; - fAphi = nullptr; fNaphi = 0; fIfrast = 0; fMesh = 1; - fRaster = nullptr; fColorTop = 1; fColorBottom = 1; fEdgeIdx = -1; @@ -87,21 +75,12 @@ TPainter3dAlgorithms::TPainter3dAlgorithms(): TAttLine(1,1,1), TAttFill(1,0) TList *stack = nullptr; if (gCurrentHist) stack = gCurrentHist->GetPainter()->GetStack(); - fNStack = 0; - if (stack) fNStack = stack->GetSize(); - if (fNStack > kVSizeMax) { - fColorMain = new Int_t[fNStack+1]; - fColorDark = new Int_t[fNStack+1]; - fEdgeColor = new Int_t[fNStack+1]; - fEdgeStyle = new Int_t[fNStack+1]; - fEdgeWidth = new Int_t[fNStack+1]; - } else { - fColorMain = &gColorMain[0]; - fColorDark = &gColorDark[0]; - fEdgeColor = &gEdgeColor[0]; - fEdgeStyle = &gEdgeStyle[0]; - fEdgeWidth = &gEdgeWidth[0]; - } + fNStack = stack ? stack->GetSize() : 0; + fColorMain.resize(fNStack+1); + fColorDark.resize(fNStack+1); + fEdgeColor.resize(fNStack+1); + fEdgeStyle.resize(fNStack+1); + fEdgeWidth.resize(fNStack+1); for (i=0;iGetPainter()->GetStack(); - fNStack = 0; - if (stack) fNStack = stack->GetSize(); - if (fNStack > kVSizeMax) { - fColorMain = new Int_t[fNStack+1]; - fColorDark = new Int_t[fNStack+1]; - fEdgeColor = new Int_t[fNStack+1]; - fEdgeStyle = new Int_t[fNStack+1]; - fEdgeWidth = new Int_t[fNStack+1]; - } else { - fColorMain = &gColorMain[0]; - fColorDark = &gColorDark[0]; - fEdgeColor = &gEdgeColor[0]; - fEdgeStyle = &gEdgeStyle[0]; - fEdgeWidth = &gEdgeWidth[0]; - } + fNStack = stack ? stack->GetSize() : 0; + + fColorMain.resize(fNStack+1); + fColorDark.resize(fNStack+1); + fEdgeColor.resize(fNStack+1); + fEdgeStyle.resize(fNStack+1); + fEdgeWidth.resize(fNStack+1); for (i=0;i kVSizeMax) { - delete [] fColorMain; - delete [] fColorDark; - delete [] fEdgeColor; - delete [] fEdgeStyle; - delete [] fEdgeWidth; - } } //////////////////////////////////////////////////////////////////////////////// @@ -2054,7 +2014,7 @@ void TPainter3dAlgorithms::InitRaster(Double_t xmin, Double_t ymin, Double_t xma // Create buffer for raster Int_t buffersize = nx*ny/30 + 1; - fRaster = new Int_t[buffersize]; + fRaster.resize(buffersize); // S E T M A S K S k = 0; @@ -2271,16 +2231,8 @@ void TPainter3dAlgorithms::LegoCartesian(Double_t, Int_t nx, Int_t ny, const cha if (!tnorm) return; // Allocate v and tt arrays - Double_t *v, *tt; Int_t vSize = fNStack+2; - if (vSize > kVSizeMax) { - v = new Double_t[vSize]; - tt = new Double_t[4*vSize]; - } else { - vSize = kVSizeMax; - v = &gV[0]; - tt = &gTT[0]; - } + std::vector v(vSize), tt(4*vSize); // Define order of drawing Int_t incrx = (tnorm[8] < 0.) ? -1 : +1; @@ -2312,7 +2264,7 @@ void TPainter3dAlgorithms::LegoCartesian(Double_t, Int_t nx, Int_t ny, const cha for (Int_t iy = iy1; iy != iy2+incry; iy += incry) { for (Int_t ix = ix1; ix != ix2+incrx; ix += incrx) { if (!painter->IsInside(ix,iy)) continue; - (this->*fLegoFunction)(ix, iy, nv, xy, v, tt); + (this->*fLegoFunction)(ix, iy, nv, xy, v.data(), tt.data()); if (nv < 2 || nv > vSize) continue; if (Hoption.Zero) { Double_t total_content = 0; @@ -2396,10 +2348,6 @@ void TPainter3dAlgorithms::LegoCartesian(Double_t, Int_t nx, Int_t ny, const cha } } } - if (vSize > kVSizeMax) { - delete [] v; - delete [] tt; - } } //////////////////////////////////////////////////////////////////////////////// @@ -2444,11 +2392,10 @@ void TPainter3dAlgorithms::LegoPolar(Int_t iordr, Int_t na, Int_t nb, const char nphi = na; } if (fNaphi < nphi + 3) { - if (fAphi) { delete [] fAphi; fAphi = 0; } fNaphi = nphi + 3; - fAphi = new Double_t[fNaphi]; + fAphi.resize(fNaphi); } - if (fAphi == 0) { + if (fAphi.empty()) { Error("LegoPolar", "failed to allocate array fAphi[%d]", fNaphi); fNaphi = 0; return; @@ -2457,16 +2404,8 @@ void TPainter3dAlgorithms::LegoPolar(Int_t iordr, Int_t na, Int_t nb, const char if (*chopt == 'B' || *chopt == 'b') iopt = 1; // Allocate v and tt arrays - Double_t *v, *tt; Int_t vSize = fNStack+2; - if (vSize > kVSizeMax) { - v = new Double_t[vSize]; - tt = new Double_t[4*vSize]; - } else { - vSize = kVSizeMax; - v = &gV[0]; - tt = &gTT[0]; - } + std::vector v(vSize), tt(4*vSize); // P R E P A R E P H I A R R A Y // F I N D C R I T I C A L S E C T O R S @@ -2477,19 +2416,19 @@ void TPainter3dAlgorithms::LegoPolar(Int_t iordr, Int_t na, Int_t nb, const char for (i = 1; i <= nphi; ++i) { if (iordr == 0) ib = i; if (iordr != 0) ia = i; - (this->*fLegoFunction)(ia, ib, nv, ab, v, tt); + (this->*fLegoFunction)(ia, ib, nv, ab, v.data(), tt.data()); if (i == 1) fAphi[0] = ab[jphi - 1]; fAphi[i - 1] = (fAphi[i - 1] + ab[jphi - 1]) / (float)2.; fAphi[i] = ab[jphi + 3]; } - view->FindPhiSectors(iopt, kphi, fAphi, iphi1, iphi2); + view->FindPhiSectors(iopt, kphi, fAphi.data(), iphi1, iphi2); // E N C O D E V I S I B I L I T Y O F S I D E S // A N D O R D E R A L O N G R for (i = 1; i <= nphi; ++i) { if (!iordr) ib = i; if (iordr) ia = i; - (this->*fLegoFunction)(ia, ib, nv, ab, v, tt); + (this->*fLegoFunction)(ia, ib, nv, ab, v.data(), tt.data()); SideVisibilityEncode(iopt, ab[jphi - 1]*kRad, ab[jphi + 3]*kRad, fAphi[i - 1]); } @@ -2508,7 +2447,7 @@ void TPainter3dAlgorithms::LegoPolar(Int_t iordr, Int_t na, Int_t nb, const char for (ir = ir1; incrr < 0 ? ir >= ir2 : ir <= ir2; ir += incrr) { if (iordr == 0) { ia = ir; ib = iphi; } else { ia = iphi; ib = ir; } - (this->*fLegoFunction)(ia, ib, nv, ab, v, tt); + (this->*fLegoFunction)(ia, ib, nv, ab, v.data(), tt.data()); if (nv < 2 || nv > vSize) continue; if (Hoption.Zero) { Double_t total_content=0; @@ -2602,13 +2541,8 @@ void TPainter3dAlgorithms::LegoPolar(Int_t iordr, Int_t na, Int_t nb, const char if (iphi == 0) iphi = kphi; if (iphi > kphi) iphi = 1; if (iphi != iphi2) goto L100; - if (incr == 0) { - if (vSize > kVSizeMax) { - delete [] v; - delete [] tt; - } + if (incr == 0) return; - } if (incr < 0) { incr = 0; goto L100; @@ -2663,11 +2597,10 @@ void TPainter3dAlgorithms::LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, cons nphi = na; } if (fNaphi < nphi + 3) { - if (fAphi) { delete [] fAphi; fAphi = 0; } fNaphi = nphi + 3; - fAphi = new Double_t[fNaphi]; + fAphi.resize(fNaphi); } - if (fAphi == 0) { + if (fAphi.empty()) { Error("LegoCylindrical", "failed to allocate array fAphi[%d]", fNaphi); fNaphi = 0; return; @@ -2676,16 +2609,8 @@ void TPainter3dAlgorithms::LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, cons if (*chopt == 'B' || *chopt == 'b') iopt = 1; // Allocate v and tt arrays - Double_t *v, *tt; Int_t vSize = fNStack+2; - if (vSize > kVSizeMax) { - v = new Double_t[vSize]; - tt = new Double_t[4*vSize]; - } else { - vSize = kVSizeMax; - v = &gV[0]; - tt = &gTT[0]; - } + std::vector v(vSize), tt(4*vSize); // P R E P A R E P H I A R R A Y // F I N D C R I T I C A L S E C T O R S @@ -2696,19 +2621,19 @@ void TPainter3dAlgorithms::LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, cons for (i = 1; i <= nphi; ++i) { if (iordr == 0) ib = i; if (iordr != 0) ia = i; - (this->*fLegoFunction)(ia, ib, nv, ab, v, tt); + (this->*fLegoFunction)(ia, ib, nv, ab, v.data(), tt.data()); if (i == 1) fAphi[0] = ab[jphi - 1]; fAphi[i - 1] = (fAphi[i - 1] + ab[jphi - 1]) / (float)2.; fAphi[i] = ab[jphi + 3]; } - view->FindPhiSectors(iopt, kphi, fAphi, iphi1, iphi2); + view->FindPhiSectors(iopt, kphi, fAphi.data(), iphi1, iphi2); // E N C O D E V I S I B I L I T Y O F S I D E S // A N D O R D E R A L O N G R for (i = 1; i <= nphi; ++i) { if (iordr == 0) ib = i; if (iordr != 0) ia = i; - (this->*fLegoFunction)(ia, ib, nv, ab, v, tt); + (this->*fLegoFunction)(ia, ib, nv, ab, v.data(), tt.data()); SideVisibilityEncode(iopt, ab[jphi - 1]*kRad, ab[jphi + 3]*kRad, fAphi[i - 1]); } @@ -2733,7 +2658,7 @@ void TPainter3dAlgorithms::LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, cons for (iz = iz1; incrz < 0 ? iz >= iz2 : iz <= iz2; iz += incrz) { if (iordr == 0) {ia = iz; ib = iphi;} else {ia = iphi; ib = iz;} - (this->*fLegoFunction)(ia, ib, nv, ab, v, tt); + (this->*fLegoFunction)(ia, ib, nv, ab, v.data(), tt.data()); if (nv < 2 || nv > vSize) continue; icodes[0] = ia; icodes[1] = ib; @@ -2823,13 +2748,8 @@ void TPainter3dAlgorithms::LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, cons if (iphi == 0) iphi = kphi; if (iphi > kphi) iphi = 1; if (iphi != iphi2) goto L100; - if (incr == 0) { - if (vSize > kVSizeMax) { - delete [] v; - delete [] tt; - } + if (incr == 0) return; - } if (incr < 0) { incr = 0; goto L100; @@ -2886,11 +2806,10 @@ void TPainter3dAlgorithms::LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int nphi = na; } if (fNaphi < nth + 3 || fNaphi < nphi + 3) { - if (fAphi) { delete [] fAphi; fAphi = 0; } fNaphi = TMath::Max(nth, nphi) + 3; - fAphi = new Double_t[fNaphi]; + fAphi.resize(fNaphi); } - if (fAphi == 0) { + if (fAphi.empty()) { Error("LegoSpherical", "failed to allocate array fAphi[%d]", fNaphi); fNaphi = 0; return; @@ -2899,16 +2818,8 @@ void TPainter3dAlgorithms::LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int if (*chopt == 'B' || *chopt == 'b') iopt = 1; // Allocate v and tt arrays - Double_t *v, *tt; Int_t vSize = fNStack+2; - if (vSize > kVSizeMax) { - v = new Double_t[vSize]; - tt = new Double_t[4*vSize]; - } else { - vSize = kVSizeMax; - v = &gV[0]; - tt = &gTT[0]; - } + std::vector v(vSize), tt(4*vSize); // P R E P A R E P H I A R R A Y // F I N D C R I T I C A L P H I S E C T O R S @@ -2921,12 +2832,12 @@ void TPainter3dAlgorithms::LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int for (i = 1; i <= nphi; ++i) { if (iordr == 0) ib = i; if (iordr != 0) ia = i; - (this->*fLegoFunction)(ia, ib, nv, ab, v, tt); + (this->*fLegoFunction)(ia, ib, nv, ab, v.data(), tt.data()); if (i == 1) fAphi[0] = ab[jphi - 1]; fAphi[i - 1] = (fAphi[i - 1] + ab[jphi - 1]) / (float)2.; fAphi[i] = ab[jphi + 3]; } - view->FindPhiSectors(iopt, kphi, fAphi, iphi1, iphi2); + view->FindPhiSectors(iopt, kphi, fAphi.data(), iphi1, iphi2); // P R E P A R E T H E T A A R R A Y if (iordr == 0) ib = 1; @@ -2934,7 +2845,7 @@ void TPainter3dAlgorithms::LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int for (i = 1; i <= nth; ++i) { if (iordr == 0) ia = i; if (iordr != 0) ib = i; - (this->*fLegoFunction)(ia, ib, nv, ab, v, tt); + (this->*fLegoFunction)(ia, ib, nv, ab, v.data(), tt.data()); if (i == 1) fAphi[0] = ab[jth - 1]; fAphi[i - 1] = (fAphi[i - 1] + ab[jth - 1]) / (float)2.; fAphi[i] = ab[jth + 3]; @@ -2949,18 +2860,18 @@ void TPainter3dAlgorithms::LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int if (iphi > nphi) goto L500; // F I N D C R I T I C A L T H E T A S E C T O R S - if (!iordr) {ia = mth; ib = iphi; } - else {ia = iphi;ib = mth; } - (this->*fLegoFunction)(ia, ib, nv, ab, v, tt); + if (!iordr) {ia = mth; ib = iphi; } + else {ia = iphi; ib = mth; } + (this->*fLegoFunction)(ia, ib, nv, ab, v.data(), tt.data()); phi = (ab[jphi - 1] + ab[jphi + 3]) / (float)2.; - view->FindThetaSectors(iopt, phi, kth, fAphi, ith1, ith2); + view->FindThetaSectors(iopt, phi, kth, fAphi.data(), ith1, ith2); incrth = 1; ith = ith1; L200: if (ith > nth) goto L400; if (iordr == 0) ia = ith; if (iordr != 0) ib = ith; - (this->*fLegoFunction)(ia, ib, nv, ab, v, tt); + (this->*fLegoFunction)(ia, ib, nv, ab, v.data(), tt.data()); if (nv < 2 || nv > vSize) goto L400; // D E F I N E V I S I B I L I T Y O F S I D E S @@ -3106,13 +3017,8 @@ void TPainter3dAlgorithms::LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int if (iphi == 0) iphi = kphi; if (iphi > kphi) iphi = 1; if (iphi != iphi2) goto L100; - if (incr == 0) { - if (vSize > kVSizeMax) { - delete [] v; - delete [] tt; - } + if (incr == 0) return; - } if (incr < 0) { incr = 0; goto L100; @@ -3703,11 +3609,10 @@ void TPainter3dAlgorithms::SurfacePolar(Int_t iordr, Int_t na, Int_t nb, const c nphi = na; } if (fNaphi < nphi + 3) { - if (fAphi) { delete [] fAphi; fAphi = 0; } - fNaphi =nphi + 3; - fAphi = new Double_t[fNaphi]; + fNaphi = nphi + 3; + fAphi.resize(fNaphi); } - if (fAphi == 0) { + if (fAphi.empty()) { Error("SurfacePolar", "failed to allocate array fAphi[%d]", fNaphi); fNaphi = 0; return; @@ -3728,7 +3633,7 @@ void TPainter3dAlgorithms::SurfacePolar(Int_t iordr, Int_t na, Int_t nb, const c fAphi[i - 1] = (fAphi[i - 1] + f[jphi - 1]) / (float)2.; fAphi[i] = f[jphi + 5]; } - view->FindPhiSectors(iopt, kphi, fAphi, iphi1, iphi2); + view->FindPhiSectors(iopt, kphi, fAphi.data(), iphi1, iphi2); // D R A W S U R F A C E icodes[2] = -1; // -1 for data, 0 for front a back boxes @@ -3833,11 +3738,10 @@ void TPainter3dAlgorithms::SurfaceCylindrical(Int_t iordr, Int_t na, Int_t nb, c nphi = na; } if (fNaphi < nphi + 3) { - if (fAphi) { delete [] fAphi; fAphi = 0; } - fNaphi =nphi + 3; - fAphi = new Double_t[fNaphi]; + fNaphi = nphi + 3; + fAphi.resize(fNaphi); } - if (fAphi == 0) { + if (fAphi.empty()) { Error("SurfaceCylindrical", "failed to allocate array fAphi[%d]", fNaphi); fNaphi = 0; return; @@ -3858,7 +3762,7 @@ void TPainter3dAlgorithms::SurfaceCylindrical(Int_t iordr, Int_t na, Int_t nb, c fAphi[i - 1] = (fAphi[i - 1] + f[jphi - 1]) / (float)2.; fAphi[i] = f[jphi + 5]; } - view->FindPhiSectors(iopt, kphi, fAphi, iphi1, iphi2); + view->FindPhiSectors(iopt, kphi, fAphi.data(), iphi1, iphi2); // F I N D O R D E R A L O N G Z incrz = 1; @@ -3955,11 +3859,10 @@ void TPainter3dAlgorithms::SurfaceSpherical(Int_t ipsdr, Int_t iordr, Int_t na, nphi = na; } if (fNaphi < nth + 3 || fNaphi < nphi + 3) { - if (fAphi) { delete [] fAphi; fAphi = 0; } fNaphi = TMath::Max(nth, nphi) + 3; - fAphi = new Double_t[fNaphi]; + fAphi.resize(fNaphi); } - if (fAphi == 0) { + if (fAphi.empty()) { Error("SurfaceSpherical", "failed to allocate array fAphi[%d]", fNaphi); fNaphi = 0; return; @@ -3982,7 +3885,7 @@ void TPainter3dAlgorithms::SurfaceSpherical(Int_t ipsdr, Int_t iordr, Int_t na, fAphi[i - 1] = (fAphi[i - 1] + f[jphi - 1]) / (float)2.; fAphi[i] = f[jphi + 5]; } - view->FindPhiSectors(iopt, kphi, fAphi, iphi1, iphi2); + view->FindPhiSectors(iopt, kphi, fAphi.data(), iphi1, iphi2); // P R E P A R E T H E T A A R R A Y if (iordr == 0) ib = 1; @@ -4012,7 +3915,7 @@ void TPainter3dAlgorithms::SurfaceSpherical(Int_t ipsdr, Int_t iordr, Int_t na, (this->*fSurfaceFunction)(ia, ib, f, tt); phi = (f[jphi - 1] + f[jphi + 5]) / (float)2.; - view->FindThetaSectors(iopt, phi, kth, fAphi, ith1, ith2); + view->FindThetaSectors(iopt, phi, kth, fAphi.data(), ith1, ith2); incrth = 1; ith = ith1; L200: diff --git a/hist/histpainter/src/TPainter3dAlgorithms.h b/hist/histpainter/src/TPainter3dAlgorithms.h index 088a1f2d3e86c..34ae29ae29581 100644 --- a/hist/histpainter/src/TPainter3dAlgorithms.h +++ b/hist/histpainter/src/TPainter3dAlgorithms.h @@ -13,8 +13,8 @@ #define ROOT_TPainter3dAlgorithms #include "TAttLine.h" - #include "TAttFill.h" +#include const Int_t kCARTESIAN = 1; const Int_t kPOLAR = 2; @@ -28,27 +28,27 @@ class TView; class TPainter3dAlgorithms : public TAttLine, public TAttFill { private: - Double_t fRmin[3]; ///< Lower limits of lego - Double_t fRmax[3]; ///< Upper limits of lego - Double_t *fAphi; ///< - Int_t fNaphi; ///< Size of fAphi - Int_t fSystem; ///< Coordinate system - Int_t *fColorMain; ///< - Int_t *fColorDark; ///< - Int_t fColorTop; ///< - Int_t fColorBottom; ///< - Int_t *fEdgeColor; ///< - Int_t *fEdgeStyle; ///< - Int_t *fEdgeWidth; ///< - Int_t fEdgeIdx; ///< - Int_t fMesh; ///< (=1 if mesh to draw, o otherwise) - Int_t fNStack; ///< Number of histograms in the stack to be painted - Double_t fFmin; ///< IsoSurface minimum function value - Double_t fFmax; ///< IsoSurface maximum function value - Int_t fNcolor; ///< Number of colours per Iso surface - Int_t fIc1; ///< Base colour for the 1st Iso Surface - Int_t fIc2; ///< Base colour for the 2nd Iso Surface - Int_t fIc3; ///< Base colour for the 3rd Iso Surface + Double_t fRmin[3]; ///< Lower limits of lego + Double_t fRmax[3]; ///< Upper limits of lego + std::vector fAphi; ///< + Int_t fNaphi; ///< Size of fAphi + Int_t fSystem; ///< Coordinate system + std::vector fColorMain; ///< + std::vector fColorDark; ///< + Int_t fColorTop; ///< + Int_t fColorBottom; ///< + std::vector fEdgeColor; ///< + std::vector fEdgeStyle; ///< + std::vector fEdgeWidth; ///< + Int_t fEdgeIdx; ///< + Int_t fMesh; ///< (=1 if mesh to draw, o otherwise) + Int_t fNStack; ///< Number of histograms in the stack to be painted + Double_t fFmin; ///< IsoSurface minimum function value + Double_t fFmax; ///< IsoSurface maximum function value + Int_t fNcolor; ///< Number of colours per Iso surface + Int_t fIc1; ///< Base colour for the 1st Iso Surface + Int_t fIc2; ///< Base colour for the 2nd Iso Surface + Int_t fIc3; ///< Base colour for the 3rd Iso Surface public: typedef void (TPainter3dAlgorithms::*DrawFaceFunc_t)(Int_t *, Double_t *, Int_t, Int_t *, Double_t *); @@ -171,16 +171,16 @@ class TPainter3dAlgorithms : public TAttLine, public TAttFill { void FillPolygonBorder(Int_t nn, Double_t *xy); private: - Double_t fXrast; ///< Minimal x - Double_t fYrast; ///< Minimal y - Double_t fDXrast; ///< X size - Double_t fDYrast; ///< Y size - Int_t fNxrast; ///< Number of pixels in x - Int_t fNyrast; ///< Number of pixels in y - Int_t fIfrast; ///< Flag, if it not zero them the algorithm is off - Int_t *fRaster; ///< Pointer to raster buffer - Int_t fJmask[30]; ///< Indices of subsets of n-bit masks (n is from 1 to 30) - Int_t fMask[465]; ///< Set of masks (30+29+28+...+1)=465 + Double_t fXrast; ///< Minimal x + Double_t fYrast; ///< Minimal y + Double_t fDXrast; ///< X size + Double_t fDYrast; ///< Y size + Int_t fNxrast; ///< Number of pixels in x + Int_t fNyrast; ///< Number of pixels in y + Int_t fIfrast; ///< Flag, if it not zero them the algorithm is off + std::vector fRaster; ///< Pointer to raster buffer + Int_t fJmask[30]; ///< Indices of subsets of n-bit masks (n is from 1 to 30) + Int_t fMask[465]; ///< Set of masks (30+29+28+...+1)=465 ///@} ///@{ From ea5fe9937d5f4ef5cc1d5e1de05a98f85114609c Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Mon, 27 Jun 2022 14:52:20 +0200 Subject: [PATCH 035/104] Use nullptr in 3d algorithms --- hist/histpainter/src/TPainter3dAlgorithms.cxx | 96 +++++++------------ 1 file changed, 35 insertions(+), 61 deletions(-) diff --git a/hist/histpainter/src/TPainter3dAlgorithms.cxx b/hist/histpainter/src/TPainter3dAlgorithms.cxx index 24cf5d929879f..2910722550fc0 100644 --- a/hist/histpainter/src/TPainter3dAlgorithms.cxx +++ b/hist/histpainter/src/TPainter3dAlgorithms.cxx @@ -69,9 +69,9 @@ TPainter3dAlgorithms::TPainter3dAlgorithms(): TAttLine(1,1,1), TAttFill(1,0) fEdgeIdx = -1; fNlevel = 0; fSystem = kCARTESIAN; - fDrawFace = 0; - fLegoFunction = 0; - fSurfaceFunction = 0; + fDrawFace = nullptr; + fLegoFunction = nullptr; + fSurfaceFunction = nullptr; TList *stack = nullptr; if (gCurrentHist) stack = gCurrentHist->GetPainter()->GetStack(); @@ -143,9 +143,9 @@ TPainter3dAlgorithms::TPainter3dAlgorithms(Double_t *rmin, Double_t *rmax, Int_t fSystem = system; if (system == kCARTESIAN || system == kPOLAR) psi = 0; else psi = 90; - fDrawFace = 0; - fLegoFunction = 0; - fSurfaceFunction = 0; + fDrawFace = nullptr; + fLegoFunction = nullptr; + fSurfaceFunction = nullptr; TList *stack = gCurrentHist->GetPainter()->GetStack(); fNStack = stack ? stack->GetSize() : 0; @@ -194,9 +194,9 @@ TPainter3dAlgorithms::TPainter3dAlgorithms(Double_t *rmin, Double_t *rmax, Int_t fDYrast = 0.; fDX = 0.; - TView *view = 0; - if (gPad) view = gPad->GetView(); - if (!view) view = TView::CreateView(fSystem, rmin, rmax); + TView *view = gPad ? gPad->GetView() : nullptr; + if (!view) + view = TView::CreateView(fSystem, rmin, rmax); if (view) { view->SetView(gPad->GetPhi(), gPad->GetTheta(), psi, i); view->SetRange(rmin,rmax); @@ -220,8 +220,7 @@ void TPainter3dAlgorithms::BackBox(Double_t ang) static Int_t iface1[4] = { 1, 4, 8, 5 }; static Int_t iface2[4] = { 4, 3, 7, 8 }; - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("BackBox", "no TView in current pad"); return; @@ -264,8 +263,7 @@ void TPainter3dAlgorithms::FrontBox(Double_t ang) static Int_t iface1[4] = { 1, 2, 6, 5 }; static Int_t iface2[4] = { 2, 3, 7, 6 }; - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("FrontBox", "no TView in current pad"); return; @@ -367,8 +365,7 @@ void TPainter3dAlgorithms::ColorFunction(Int_t nl, Double_t *fl, Int_t *icl, Int void TPainter3dAlgorithms::DefineGridLevels(Int_t ndivz) { - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("GridLevels", "no TView in current pad"); return; @@ -408,8 +405,7 @@ void TPainter3dAlgorithms::DefineGridLevels(Int_t ndivz) void TPainter3dAlgorithms::DrawFaceMode1(Int_t *, Double_t *xyz, Int_t np, Int_t *iface, Double_t *) { - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) return; // Transfer to normalised coordinates @@ -458,8 +454,7 @@ void TPainter3dAlgorithms::DrawFaceMode1(Int_t *, Double_t *xyz, Int_t np, Int_t void TPainter3dAlgorithms::DrawFaceMode2(Int_t *, Double_t *xyz, Int_t np, Int_t *iface, Double_t *t) { - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) return; // Transfer to normalised coordinates @@ -514,8 +509,7 @@ void TPainter3dAlgorithms::DrawFaceMode2(Int_t *, Double_t *xyz, Int_t np, Int_t void TPainter3dAlgorithms::DrawFaceMode3(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *) { - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) return; // Transfer to normalised coordinates @@ -562,8 +556,7 @@ void TPainter3dAlgorithms::DrawFaceMode3(Int_t *icodes, Double_t *xyz, Int_t np, void TPainter3dAlgorithms::DrawFaceMove1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt) { - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) return; // Copy points to array @@ -651,8 +644,7 @@ void TPainter3dAlgorithms::DrawFaceMove1(Int_t *icodes, Double_t *xyz, Int_t np, void TPainter3dAlgorithms::DrawFaceMove2(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *) { - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) return; // Copy points to array @@ -713,8 +705,7 @@ void TPainter3dAlgorithms::DrawFaceMove2(Int_t *icodes, Double_t *xyz, Int_t np, void TPainter3dAlgorithms::DrawFaceMove3(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt) { - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) return; // Set graphics attributes @@ -797,8 +788,7 @@ void TPainter3dAlgorithms::DrawFaceMove3(Int_t *icodes, Double_t *xyz, Int_t np, void TPainter3dAlgorithms::DrawLevelLines(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt) { - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) return; // Set graphics attributes @@ -866,8 +856,7 @@ void TPainter3dAlgorithms::DrawLevelLines(Int_t *icodes, Double_t *xyz, Int_t np void TPainter3dAlgorithms::DrawFaceRaster1(Int_t *icodes, Double_t *xyz, Int_t np, Int_t *iface, Double_t *tt) { - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) return; // Copy vertices to array @@ -955,8 +944,7 @@ void TPainter3dAlgorithms::DrawFaceRaster1(Int_t *icodes, Double_t *xyz, Int_t n void TPainter3dAlgorithms::DrawFaceRaster2(Int_t *, Double_t *xyz, Int_t np, Int_t *iface, Double_t *) { - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) return; // Copy vertices to array @@ -1538,9 +1526,8 @@ void TPainter3dAlgorithms::FindVisibleDraw(Double_t *r1, Double_t *r2) /* Parameter adjustments */ --r2; --r1; - TView *view = 0; + TView *view = gPad ? gPad->GetView() : nullptr; - if (gPad) view = gPad->GetView(); if (view) { tn = view->GetTN(); if (tn) { @@ -2221,8 +2208,7 @@ void TPainter3dAlgorithms::LegoCartesian(Double_t, Int_t nx, Int_t ny, const cha Double_t xy[4*2], xyz[8*3], tface[4]; Int_t firstStackNumberDrawn=-1 ; // necessary to compute fColorBottom when the 0 option is set and when the stack is seen from below (bottomview, theta<0.) - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("LegoCartesian", "no TView in current pad"); return; @@ -2371,10 +2357,9 @@ void TPainter3dAlgorithms::LegoPolar(Int_t iordr, Int_t na, Int_t nb, const char Int_t ir, jr, iv, nr, nv, icodes[4]; Double_t xyz[24]; // was [3][8] ia = ib = 0; - TView *view = 0; - Int_t firstStackNumberDrawn=-1 ; // necessary to compute fColorBottom when the 0 option is set and when the stack is seen from below (bottomview, theta<0.) + Int_t firstStackNumberDrawn = -1 ; // necessary to compute fColorBottom when the 0 option is set and when the stack is seen from below (bottomview, theta<0.) - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("LegoPolar", "no TView in current pad"); return; @@ -2576,10 +2561,9 @@ void TPainter3dAlgorithms::LegoCylindrical(Int_t iordr, Int_t na, Int_t nb, cons Double_t sinphi[4]; Double_t xyz[24]; // was [3][8] ia = ib = 0; - TView *view = 0; Int_t firstStackNumberDrawn=-1 ; // necessary to compute fColorBottom when the 0 option is set and when the stack is seen from below (bottomview, theta<0.) - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("LegoCylindrical", "no TView in current pad"); return; @@ -2785,10 +2769,9 @@ void TPainter3dAlgorithms::LegoSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Int Double_t xyz[24]; // was [3][8] Double_t phi1, phi2; ia = ib = 0; - TView *view = 0; Int_t firstStackNumberDrawn=-1 ; // necessary to compute fColorBottom when the 0 option is set and when the stack is seen from below (bottomview, theta<0.) - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("LegoSpherical", "no TView in current pad"); return; @@ -3153,8 +3136,7 @@ void TPainter3dAlgorithms::ModifyScreen(Double_t *r1, Double_t *r2) --r2; --r1; - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (view) { tn = view->GetTN(); @@ -3296,9 +3278,8 @@ void TPainter3dAlgorithms::SideVisibilityEncode(Int_t iopt, Double_t phi1, Doubl /* Local variables */ Double_t zn, phi; Int_t k = 0; - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("SideVisibilityEncode", "no TView in current pad"); return; @@ -3392,8 +3373,7 @@ void TPainter3dAlgorithms::SurfaceCartesian(Double_t, Int_t nx, Int_t ny, const Int_t icodes[3]; Double_t f[4*3], tt[4], xyz[4*3]; - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("SurfaceCartesian", "no TView in current pad"); return; @@ -3580,9 +3560,8 @@ void TPainter3dAlgorithms::SurfacePolar(Int_t iordr, Int_t na, Int_t nb, const c { /* Initialized data */ static Int_t iface[4] = { 1,2,3,4 }; - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("SurfacePolar", "no TView in current pad"); return; @@ -3718,9 +3697,8 @@ void TPainter3dAlgorithms::SurfaceCylindrical(Int_t iordr, Int_t na, Int_t nb, c Double_t tt[4]; Double_t ttt[4], xyz[12] /* was [3][4] */; ia = ib = 0; - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("SurfaceCylindrical", "no TView in current pad"); return; @@ -3839,9 +3817,8 @@ void TPainter3dAlgorithms::SurfaceSpherical(Int_t ipsdr, Int_t iordr, Int_t na, Double_t phi; Double_t ttt[4], xyz[12] /* was [3][4] */; ia = ib = 0; - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("SurfaceSpherical", "no TView in current pad"); return; @@ -5483,9 +5460,7 @@ void TPainter3dAlgorithms::IsoSurface (Int_t ns, Double_t *s, Int_t nx, xyzn[i][2] = 0.; } - TView *view = 0; - - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("ImplicitFunction", "no TView in current pad"); return; @@ -5772,9 +5747,8 @@ void TPainter3dAlgorithms::DrawFaceGouraudShaded(Int_t *icodes, { Int_t i, k, irep; Double_t p3[12][3]; - TView *view = 0; - if (gPad) view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("ImplicitFunction", "no TView in current pad"); return; From ac254ff40182ebaadd25d9a8f011a9018873b92e Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Mon, 27 Jun 2022 16:15:40 +0200 Subject: [PATCH 036/104] Use members instead of global variables in graph painter Use members like `std::vector gxwork` for coordinates buffers instead of global plain arrays. --- hist/histpainter/inc/TGraphPainter.h | 3 + hist/histpainter/src/TGraphPainter.cxx | 148 ++++++++++++------------- hist/histpainter/src/TPaletteAxis.cxx | 8 +- 3 files changed, 80 insertions(+), 79 deletions(-) diff --git a/hist/histpainter/inc/TGraphPainter.h b/hist/histpainter/inc/TGraphPainter.h index 7e23b643adc0b..94dea04709c15 100644 --- a/hist/histpainter/inc/TGraphPainter.h +++ b/hist/histpainter/inc/TGraphPainter.h @@ -22,6 +22,7 @@ ////////////////////////////////////////////////////////////////////////// #include "TVirtualGraphPainter.h" +#include class TGraph; class TF1; @@ -63,6 +64,8 @@ class TGraphPainter : public TVirtualGraphPainter { static Int_t fgMaxPointsPerLine; //Number of points per chunks' line when drawing a graph. + std::vector gxwork, gywork, gxworkl, gyworkl; // buffers for coordinates + ClassDefOverride(TGraphPainter,0) // TGraph painter }; diff --git a/hist/histpainter/src/TGraphPainter.cxx b/hist/histpainter/src/TGraphPainter.cxx index e55569aac80ee..1a461cf7e1dde 100644 --- a/hist/histpainter/src/TGraphPainter.cxx +++ b/hist/histpainter/src/TGraphPainter.cxx @@ -39,7 +39,6 @@ #include "snprintf.h" #include -Double_t *gxwork, *gywork, *gxworkl, *gyworkl; Int_t TGraphPainter::fgMaxPointsPerLine = 50; static Int_t gHighlightPoint = -1; // highlight point of graph @@ -672,9 +671,9 @@ TGraphPainter::~TGraphPainter() //////////////////////////////////////////////////////////////////////////////// -/// Compute the logarithm of global variables `gxwork` and `gywork` -/// according to the value of Options and put the results in the global -/// variables `gxworkl` and `gyworkl`. +/// Compute the logarithm of variables `gxwork` and `gywork` +/// according to the value of Options and put the results +/// in the variables `gxworkl` and `gyworkl`. /// /// npoints : Number of points in gxwork and in gywork. /// @@ -683,22 +682,21 @@ TGraphPainter::~TGraphPainter() void TGraphPainter::ComputeLogs(Int_t npoints, Int_t opt) { - - - Int_t i; - memcpy(gxworkl,gxwork,npoints*8); - memcpy(gyworkl,gywork,npoints*8); if (gPad->GetLogx()) { - for (i=0;i 0) gxworkl[i] = TMath::Log10(gxworkl[i]); - else gxworkl[i] = gPad->GetX1(); + for (Int_t i = 0; i < npoints; i++) { + gxworkl[i] = (gxwork[i] > 0.) ? TMath::Log10(gxwork[i]) : gPad->GetX1(); } + } else { + for (Int_t i = 0; i < npoints; i++) + gxworkl[i] = gxwork[i]; } if (!opt && gPad->GetLogy()) { - for (i=0;i 0) gyworkl[i] = TMath::Log10(gyworkl[i]); - else gyworkl[i] = gPad->GetY1(); + for (Int_t i = 0; i < npoints; i++) { + gyworkl[i] = (gywork[i] > 0.) ? TMath::Log10(gywork[i]) : gPad->GetY1(); } + } else { + for (Int_t i = 0; i < npoints; i++) + gyworkl[i] = gywork[i]; } } @@ -1126,11 +1124,11 @@ Int_t TGraphPainter::GetHighlightPoint(TGraph *theGraph) const void TGraphPainter::SetHighlight(TGraph *theGraph) { gHighlightPoint = -1; // must be -1 - gHighlightGraph = 0; + gHighlightGraph = nullptr; if (theGraph->IsHighlight()) return; // delete previous highlight marker - if (gHighlightMarker) { gHighlightMarker->Delete(); gHighlightMarker = 0; } + if (gHighlightMarker) { gHighlightMarker->Delete(); gHighlightMarker = nullptr; } // emit Highlighted() signal (user can check on disabled) if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, theGraph, gHighlightPoint, -1); } @@ -1449,10 +1447,10 @@ void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t * theGraph->TAttMarker::Modify(); // Draw the graph with a polyline or a fill area - gxwork = new Double_t[2*npoints+10]; - gywork = new Double_t[2*npoints+10]; - gxworkl = new Double_t[2*npoints+10]; - gyworkl = new Double_t[2*npoints+10]; + gxwork.resize(2*npoints+10); + gywork.resize(2*npoints+10); + gxworkl.resize(2*npoints+10); + gyworkl.resize(2*npoints+10); if (optionLine || optionFill) { x1 = x[0]; @@ -1474,21 +1472,21 @@ void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t * Int_t bord = gStyle->GetDrawBorder(); if (optionR) { if (optionFill) { - gPad->PaintFillArea(npt,gyworkl,gxworkl); - if (bord) gPad->PaintPolyLine(npt,gyworkl,gxworkl); + gPad->PaintFillArea(npt,gyworkl.data(),gxworkl.data()); + if (bord) gPad->PaintPolyLine(npt,gyworkl.data(),gxworkl.data()); } if (optionLine) { - if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, gyworkl, gxworkl); - gPad->PaintPolyLine(npt,gyworkl,gxworkl); + if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, gyworkl.data(), gxworkl.data()); + gPad->PaintPolyLine(npt,gyworkl.data(),gxworkl.data()); } } else { if (optionFill) { - gPad->PaintFillArea(npt,gxworkl,gyworkl); - if (bord) gPad->PaintPolyLine(npt,gxworkl,gyworkl); + gPad->PaintFillArea(npt,gxworkl.data(),gyworkl.data()); + if (bord) gPad->PaintPolyLine(npt,gxworkl.data(),gyworkl.data()); } if (optionLine) { - if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, gxworkl, gyworkl); - gPad->PaintPolyLine(npt,gxworkl,gyworkl); + if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, gxworkl.data(), gyworkl.data()); + gPad->PaintPolyLine(npt,gxworkl.data(),gyworkl.data()); } } gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1]; @@ -1522,7 +1520,7 @@ void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t * if (gyworkl[npt-1] < rwymin || gyworkl[npt-1] > rwymax) { if (npt > 2) { ComputeLogs(npt, optionZ); - Smooth(theGraph, npt,gxworkl,gyworkl,drawtype); + Smooth(theGraph, npt,gxworkl.data(),gyworkl.data(),drawtype); } gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1]; npt=1; @@ -1531,7 +1529,7 @@ void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t * } if (npt > 1) { ComputeLogs(npt, optionZ); - Smooth(theGraph, npt,gxworkl,gyworkl,drawtype); + Smooth(theGraph, npt,gxworkl.data(),gyworkl.data(),drawtype); } } else { drawtype += 10; @@ -1549,7 +1547,7 @@ void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t * if (gxworkl[npt-1] < rwxmin || gxworkl[npt-1] > rwxmax) { if (npt > 2) { ComputeLogs(npt, optionZ); - Smooth(theGraph, npt,gxworkl,gyworkl,drawtype); + Smooth(theGraph, npt,gxworkl.data(),gyworkl.data(),drawtype); } gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1]; npt=1; @@ -1558,7 +1556,7 @@ void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t * } if (npt > 1) { ComputeLogs(npt, optionZ); - Smooth(theGraph, npt,gxworkl,gyworkl,drawtype); + Smooth(theGraph, npt,gxworkl.data(),gyworkl.data(),drawtype); } } } @@ -1572,8 +1570,8 @@ void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t * npt++; if (i == npoints) { ComputeLogs(npt, optionZ); - if (optionR) gPad->PaintPolyMarker(npt,gyworkl,gxworkl); - else gPad->PaintPolyMarker(npt,gxworkl,gyworkl); + if (optionR) gPad->PaintPolyMarker(npt,gyworkl.data(),gxworkl.data()); + else gPad->PaintPolyMarker(npt,gxworkl.data(),gyworkl.data()); npt = 0; } } @@ -1587,8 +1585,8 @@ void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t * npt++; if (i == npoints) { ComputeLogs(npt, optionZ); - if (optionR) gPad->PaintPolyMarker(npt,gyworkl,gxworkl); - else gPad->PaintPolyMarker(npt,gxworkl,gyworkl); + if (optionR) gPad->PaintPolyMarker(npt,gyworkl.data(),gxworkl.data()); + else gPad->PaintPolyMarker(npt,gxworkl.data(),gyworkl.data()); npt = 0; } } @@ -1667,10 +1665,10 @@ void TGraphPainter::PaintGraph(TGraph *theGraph, Int_t npoints, const Double_t * } gPad->ResetBit(TGraph::kClipFrame); - delete [] gxwork; - delete [] gywork; - delete [] gxworkl; - delete [] gyworkl; + gxwork.clear(); + gywork.clear(); + gxworkl.clear(); + gyworkl.clear(); } @@ -1871,10 +1869,10 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ // Draw the histogram with a fill area - gxwork = new Double_t[2*npoints+10]; - gywork = new Double_t[2*npoints+10]; - gxworkl = new Double_t[2*npoints+10]; - gyworkl = new Double_t[2*npoints+10]; + gxwork.resize(2*npoints+10); + gywork.resize(2*npoints+10); + gxworkl.resize(2*npoints+10); + gyworkl.resize(2*npoints+10); if (optionFill && !optionCurve) { fillarea = kTRUE; @@ -1914,10 +1912,10 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ //transform to log ? ComputeLogs(npt, optionZ); - gPad->PaintFillArea(npt,gxworkl,gyworkl); + gPad->PaintFillArea(npt,gxworkl.data(),gyworkl.data()); if (drawborder) { if (!fillarea) gyworkl[0] = ylast; - gPad->PaintPolyLine(npt-1,gxworkl,gyworkl,noClip); + gPad->PaintPolyLine(npt-1,gxworkl.data(),gyworkl.data(),noClip); } continue; } @@ -1947,10 +1945,10 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ gywork[npt-1] = gywork[npt-2]; gxwork[npt-1] = gxwork[0]; ComputeLogs(npt, optionZ); - gPad->PaintFillArea(npt,gxworkl,gyworkl); + gPad->PaintFillArea(npt,gxworkl.data(),gyworkl.data()); if (drawborder) { if (!fillarea) gyworkl[0] = ylast; - gPad->PaintPolyLine(npt-1,gxworkl,gyworkl,noClip); + gPad->PaintPolyLine(npt-1,gxworkl.data(),gyworkl.data(),noClip); } continue; } @@ -2026,7 +2024,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ if (gxwork[nbpoints] < gPad->GetUxmax()) nbpoints++; } - gPad->PaintPolyLine(nbpoints,&gxworkl[point1],&gyworkl[point1],noClip); + gPad->PaintPolyLine(nbpoints,gxworkl.data() + point1, gyworkl.data() + point1, noClip); continue; } } //endfor (i=first; i<=last;i++) @@ -2055,7 +2053,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ gywork[npt-1] = gywork[npt-2]; gxwork[npt-1] = xwmin; ComputeLogs(npt, optionZ); - gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip); + gPad->PaintPolyLine(npt,gxworkl.data(),gyworkl.data(),noClip); continue; } } //endfor (i=first; i<=last;i++) @@ -2096,7 +2094,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ if ((gyworkl[npt-1] < rwymin) || (gyworkl[npt-1] > rwymax)) { if (npt > 2) { ComputeLogs(npt, optionZ); - Smooth(theGraph, npt,gxworkl,gyworkl,drawtype); + Smooth(theGraph, npt,gxworkl.data(),gyworkl.data(),drawtype); } gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1]; @@ -2105,7 +2103,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ } if (npt >= fgMaxPointsPerLine) { ComputeLogs(fgMaxPointsPerLine, optionZ); - Smooth(theGraph, fgMaxPointsPerLine,gxworkl,gyworkl,drawtype); + Smooth(theGraph, fgMaxPointsPerLine,gxworkl.data(),gyworkl.data(),drawtype); gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1]; npt = 1; @@ -2113,7 +2111,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ } //endfor (i=first; i<=last;i++) if (npt > 1) { ComputeLogs(npt, optionZ); - Smooth(theGraph, npt,gxworkl,gyworkl,drawtype); + Smooth(theGraph, npt,gxworkl.data(),gyworkl.data(),drawtype); } } else { drawtype = drawtype+10; @@ -2136,7 +2134,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ if ((gxworkl[npt] < uxmin) || (gxworkl[npt] > uxmax)) { if (npt > 2) { ComputeLogs(npt, optionZ); - Smooth(theGraph, npt,gxworkl,gyworkl,drawtype); + Smooth(theGraph, npt,gxworkl.data(),gyworkl.data(),drawtype); } gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1]; @@ -2145,7 +2143,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ } if (npt >= fgMaxPointsPerLine) { ComputeLogs(fgMaxPointsPerLine, optionZ); - Smooth(theGraph, fgMaxPointsPerLine,gxworkl,gyworkl,drawtype); + Smooth(theGraph, fgMaxPointsPerLine,gxworkl.data(),gyworkl.data(),drawtype); gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1]; npt = 1; @@ -2153,7 +2151,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ } //endfor (i=first; i<=last;i++) if (npt > 1) { ComputeLogs(npt, optionZ); - Smooth(theGraph, npt,gxworkl,gyworkl,drawtype); + Smooth(theGraph, npt,gxworkl.data(),gyworkl.data(),drawtype); } } } @@ -2187,7 +2185,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ if ((gywork[npt-1] < rwymin) || ((gywork[npt-1] > rwymax) && !optionFill2)) { if (npt > 2) { ComputeLogs(npt, optionZ); - gPad->PaintPolyLine(npt,gxworkl,gyworkl); + gPad->PaintPolyLine(npt,gxworkl.data(),gyworkl.data()); } gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1]; @@ -2201,9 +2199,9 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ if (optionFill2) { gxworkl[npt] = gxworkl[npt-1]; gyworkl[npt] = rwymin; gxworkl[npt+1] = gxworkl[0]; gyworkl[npt+1] = rwymin; - gPad->PaintFillArea(fgMaxPointsPerLine+2,gxworkl,gyworkl); + gPad->PaintFillArea(fgMaxPointsPerLine+2,gxworkl.data(),gyworkl.data()); } - gPad->PaintPolyLine(npt,gxworkl,gyworkl); + gPad->PaintPolyLine(npt,gxworkl.data(),gyworkl.data()); } gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1]; @@ -2215,9 +2213,9 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ if (optionFill2) { gxworkl[npt] = gxworkl[npt-1]; gyworkl[npt] = rwymin; gxworkl[npt+1] = gxworkl[0]; gyworkl[npt+1] = rwymin; - gPad->PaintFillArea(npt+2,gxworkl,gyworkl); + gPad->PaintFillArea(npt+2,gxworkl.data(),gyworkl.data()); } - gPad->PaintPolyLine(npt,gxworkl,gyworkl); + gPad->PaintPolyLine(npt,gxworkl.data(),gyworkl.data()); } } else { npt = 0; @@ -2239,7 +2237,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ if (npt > 2) { if (optionLine) { ComputeLogs(npt, optionZ); - gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip); + gPad->PaintPolyLine(npt,gxworkl.data(),gyworkl.data(),noClip); } } gxwork[0] = gxwork[npt-1]; @@ -2250,7 +2248,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ if (npt >= fgMaxPointsPerLine) { if (optionLine) { ComputeLogs(fgMaxPointsPerLine, optionZ); - gPad->PaintPolyLine(fgMaxPointsPerLine,gxworkl,gyworkl); + gPad->PaintPolyLine(fgMaxPointsPerLine,gxworkl.data(),gyworkl.data()); } gxwork[0] = gxwork[npt-1]; gywork[0] = gywork[npt-1]; @@ -2259,7 +2257,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ } //endfor (i=first; i<=last;i++) if (optionLine != 0 && npt > 1) { ComputeLogs(npt, optionZ); - gPad->PaintPolyLine(npt,gxworkl,gyworkl,noClip); + gPad->PaintPolyLine(npt,gxworkl.data(),gyworkl.data(),noClip); } } } @@ -2376,13 +2374,13 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ } if (npt >= fgMaxPointsPerLine) { ComputeLogs(npt, optionZ); - gPad->PaintPolyMarker(npt,gxworkl,gyworkl); + gPad->PaintPolyMarker(npt,gxworkl.data(),gyworkl.data()); npt = 0; } } if (npt > 0) { ComputeLogs(npt, optionZ); - gPad->PaintPolyMarker(npt,gxworkl,gyworkl); + gPad->PaintPolyMarker(npt,gxworkl.data(),gyworkl.data()); } } else { wminstep = wmin + 0.5*delta; @@ -2405,13 +2403,13 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ } if (npt >= fgMaxPointsPerLine) { ComputeLogs(npt, optionZ); - gPad->PaintPolyMarker(npt,gxworkl,gyworkl); + gPad->PaintPolyMarker(npt,gxworkl.data(),gyworkl.data()); npt = 0; } } if (npt > 0) { ComputeLogs(npt, optionZ); - gPad->PaintPolyMarker(npt,gxworkl,gyworkl); + gPad->PaintPolyMarker(npt,gxworkl.data(),gyworkl.data()); } } } @@ -2419,10 +2417,10 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ gPad->ResetBit(TGraph::kClipFrame); do_cleanup: - delete [] gxwork; - delete [] gywork; - delete [] gxworkl; - delete [] gyworkl; + gxwork.clear(); + gywork.clear(); + gxworkl.clear(); + gyworkl.clear(); } @@ -2432,8 +2430,8 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ void TGraphPainter::PaintGraphAsymmErrors(TGraph *theGraph, Option_t *option) { - Double_t *xline = 0; - Double_t *yline = 0; + Double_t *xline = nullptr; + Double_t *yline = nullptr; Int_t if1 = 0; Int_t if2 = 0; Double_t xb[4], yb[4]; diff --git a/hist/histpainter/src/TPaletteAxis.cxx b/hist/histpainter/src/TPaletteAxis.cxx index 2db40abc70ccb..0c3eb75f2c9ba 100644 --- a/hist/histpainter/src/TPaletteAxis.cxx +++ b/hist/histpainter/src/TPaletteAxis.cxx @@ -120,7 +120,7 @@ End_Macro TPaletteAxis::TPaletteAxis(): TPave() { - fH = 0; + fH = nullptr; SetName(""); } @@ -434,8 +434,8 @@ void TPaletteAxis::Paint(Option_t *) // import Attributes already here since we might need them for CJUST if (fH->GetDimension() == 2) fAxis.ImportAxisAttributes(fH->GetZaxis()); // case option "CJUST": put labels directly at color boundaries - TLatex *label = NULL; - TLine *line = NULL; + TLatex *label = nullptr; + TLine *line = nullptr; Double_t prevlab = 0; TString opt(fH->GetDrawOption()); if (opt.Contains("CJUST", TString::kIgnoreCase)) { @@ -587,7 +587,7 @@ void TPaletteAxis::UnZoom() TView *view = gPad->GetView(); if (view) { delete view; - gPad->SetView(0); + gPad->SetView(nullptr); } fH->GetZaxis()->SetRange(0, 0); if (fH->GetDimension() == 2) { From 6ea39968e2cafcb664c65903c18265cb3ba7cf2c Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Mon, 27 Jun 2022 16:34:04 +0200 Subject: [PATCH 037/104] Use std::vector and local variables in graph painter Avoid dynamic allocation of arrays and objects to exclude any kind of memory leaks --- hist/histpainter/src/TGraphPainter.cxx | 165 +++++++++++-------------- 1 file changed, 69 insertions(+), 96 deletions(-) diff --git a/hist/histpainter/src/TGraphPainter.cxx b/hist/histpainter/src/TGraphPainter.cxx index 1a461cf7e1dde..653211881708e 100644 --- a/hist/histpainter/src/TGraphPainter.cxx +++ b/hist/histpainter/src/TGraphPainter.cxx @@ -1800,15 +1800,15 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ // coverity [Calling risky function] strlcat(choptaxis, "G",10); } - TGaxis *axis = new TGaxis(); - axis->SetLineColor(gStyle->GetAxisColor("X")); - axis->SetTextColor(gStyle->GetLabelColor("X")); - axis->SetTextFont(gStyle->GetLabelFont("X")); - axis->SetLabelSize(gStyle->GetLabelSize("X")); - axis->SetLabelOffset(gStyle->GetLabelOffset("X")); - axis->SetTickSize(gStyle->GetTickLength("X")); + TGaxis axis; + axis.SetLineColor(gStyle->GetAxisColor("X")); + axis.SetTextColor(gStyle->GetLabelColor("X")); + axis.SetTextFont(gStyle->GetLabelFont("X")); + axis.SetLabelSize(gStyle->GetLabelSize("X")); + axis.SetLabelOffset(gStyle->GetLabelOffset("X")); + axis.SetTickSize(gStyle->GetTickLength("X")); - axis->PaintAxis(rwxmin,rwymin,rwxmax,rwymin,rwmin,rwmax,ndiv,choptaxis); + axis.PaintAxis(rwxmin,rwymin,rwxmax,rwymin,rwmin,rwmax,ndiv,choptaxis); choptaxis[0] = 0; rwmin = rwymin; @@ -1831,15 +1831,14 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ // coverity [Calling risky function] strlcat(choptaxis,"G",10); } - axis->SetLineColor(gStyle->GetAxisColor("Y")); - axis->SetTextColor(gStyle->GetLabelColor("Y")); - axis->SetTextFont(gStyle->GetLabelFont("Y")); - axis->SetLabelSize(gStyle->GetLabelSize("Y")); - axis->SetLabelOffset(gStyle->GetLabelOffset("Y")); - axis->SetTickSize(gStyle->GetTickLength("Y")); - - axis->PaintAxis(rwxmin,rwymin,rwxmin,rwymax,rwmin,rwmax,ndiv,choptaxis); - delete axis; + axis.SetLineColor(gStyle->GetAxisColor("Y")); + axis.SetTextColor(gStyle->GetLabelColor("Y")); + axis.SetTextFont(gStyle->GetLabelFont("Y")); + axis.SetLabelSize(gStyle->GetLabelSize("Y")); + axis.SetLabelOffset(gStyle->GetLabelOffset("Y")); + axis.SetTickSize(gStyle->GetTickLength("Y")); + + axis.PaintAxis(rwxmin,rwymin,rwxmin,rwymax,rwmin,rwmax,ndiv,choptaxis); } @@ -2430,8 +2429,7 @@ void TGraphPainter::PaintGrapHist(TGraph *theGraph, Int_t npoints, const Double_ void TGraphPainter::PaintGraphAsymmErrors(TGraph *theGraph, Option_t *option) { - Double_t *xline = nullptr; - Double_t *yline = nullptr; + std::vector xline, yline; Int_t if1 = 0; Int_t if2 = 0; Double_t xb[4], yb[4]; @@ -2480,10 +2478,10 @@ void TGraphPainter::PaintGraphAsymmErrors(TGraph *theGraph, Option_t *option) if (strchr(option,'5')) {option2 = kTRUE; option5 = kTRUE;} if (option3) { - xline = new Double_t[2*theNpoints]; - yline = new Double_t[2*theNpoints]; - if (!xline || !yline) { - Error("Paint", "too many points, out of memory"); + xline.resize(2*theNpoints); + yline.resize(2*theNpoints); + if (xline.empty() || yline.empty()) { + Error("PaintGraphAsymmErrors", "too many points, out of memory"); return; } if1 = 1; @@ -2661,12 +2659,10 @@ void TGraphPainter::PaintGraphAsymmErrors(TGraph *theGraph, Option_t *option) Int_t logy = gPad->GetLogy(); gPad->SetLogx(0); gPad->SetLogy(0); - if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC"); - else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F"); + if (option4) PaintGraph(theGraph, 2*theNpoints, xline.data(), yline.data(),"FC"); + else PaintGraph(theGraph, 2*theNpoints, xline.data(), yline.data(),"F"); gPad->SetLogx(logx); gPad->SetLogy(logy); - delete [] xline; - delete [] yline; } } @@ -2714,7 +2710,7 @@ void TGraphPainter::PaintGraphMultiErrors(TGraph *theGraph, Option_t *option) for (Int_t i = filled; i <= NYErrors; i++) options[i] = ""; - Double_t *xline = nullptr; + std::vector xline; std::vector yline(NYErrors); Int_t if1 = 0; Int_t if2 = 0; @@ -2841,10 +2837,10 @@ void TGraphPainter::PaintGraphMultiErrors(TGraph *theGraph, Option_t *option) } if (AnyOption3) { - xline = new Double_t[2 * NPointsInside]; + xline.resize(2 * NPointsInside); - if (!xline) { - Error("Paint", "too many points, out of memory"); + if (xline.empty()) { + Error("PaintGraphMultiErrors", "too many points, out of memory"); return; } @@ -2857,8 +2853,7 @@ void TGraphPainter::PaintGraphMultiErrors(TGraph *theGraph, Option_t *option) yline[j] = new Double_t[2 * NPointsInside]; if (!yline[j]) { - Error("Paint", "too many points, out of memory"); - delete[] xline; + Error("PaintGraphMultiErrors", "too many points, out of memory"); for (Int_t k = 0; k < j; k++) if (yline[k]) delete[] yline[k]; @@ -3109,16 +3104,16 @@ void TGraphPainter::PaintGraphMultiErrors(TGraph *theGraph, Option_t *option) PaintGraphSimple(tg, options[0].Data()); gPad->ResetBit(TGraph::kClipFrame); - auto tgDummy = new TGraph(); - tg->TAttFill::Copy(*tgDummy); - tg->TAttLine::Copy(*tgDummy); - tg->TAttMarker::Copy(*tgDummy); + TGraph tgDummy; + tg->TAttFill::Copy(tgDummy); + tg->TAttLine::Copy(tgDummy); + tg->TAttMarker::Copy(tgDummy); for (Int_t j = 0; j < NYErrors; j++) { if (Option3[j] && DrawErrors[j]) { if (IndividualStyles) { - tg->GetAttFill(j)->Copy(*tgDummy); - tg->GetAttLine(j)->Copy(*tgDummy); + tg->GetAttFill(j)->Copy(tgDummy); + tg->GetAttLine(j)->Copy(tgDummy); } Int_t logx = gPad->GetLogx(); @@ -3126,19 +3121,15 @@ void TGraphPainter::PaintGraphMultiErrors(TGraph *theGraph, Option_t *option) gPad->SetLogx(0); gPad->SetLogy(0); if (Option4[j]) - PaintGraph(tgDummy, 2 * NPointsInside, xline, yline[j], "FC"); + PaintGraph(&tgDummy, 2 * NPointsInside, xline.data(), yline[j], "FC"); else - PaintGraph(tgDummy, 2 * NPointsInside, xline, yline[j], "F"); + PaintGraph(&tgDummy, 2 * NPointsInside, xline.data(), yline[j], "F"); gPad->SetLogx(logx); gPad->SetLogy(logy); delete[] yline[j]; } } - delete tgDummy; - - if (AnyOption3) - delete[] xline; } //////////////////////////////////////////////////////////////////////////////// @@ -3147,8 +3138,7 @@ void TGraphPainter::PaintGraphMultiErrors(TGraph *theGraph, Option_t *option) void TGraphPainter::PaintGraphBentErrors(TGraph *theGraph, Option_t *option) { - Double_t *xline = 0; - Double_t *yline = 0; + std::vector xline, yline; Int_t if1 = 0; Int_t if2 = 0; Double_t xb[4], yb[4]; @@ -3202,10 +3192,10 @@ void TGraphPainter::PaintGraphBentErrors(TGraph *theGraph, Option_t *option) if (strchr(option,'5')) {option2 = kTRUE; option5 = kTRUE;} if (option3) { - xline = new Double_t[2*theNpoints]; - yline = new Double_t[2*theNpoints]; - if (!xline || !yline) { - Error("Paint", "too many points, out of memory"); + xline.resize(2*theNpoints); + yline.resize(2*theNpoints); + if (xline.empty() || yline.empty()) { + Error("PaintGraphBentErrors", "too many points, out of memory"); return; } if1 = 1; @@ -3387,12 +3377,10 @@ void TGraphPainter::PaintGraphBentErrors(TGraph *theGraph, Option_t *option) Int_t logy = gPad->GetLogy(); gPad->SetLogx(0); gPad->SetLogy(0); - if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC"); - else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F"); + if (option4) PaintGraph(theGraph, 2*theNpoints, xline.data(), yline.data(),"FC"); + else PaintGraph(theGraph, 2*theNpoints, xline.data(), yline.data(),"F"); gPad->SetLogx(logx); gPad->SetLogy(logy); - delete [] xline; - delete [] yline; } } @@ -3403,8 +3391,7 @@ void TGraphPainter::PaintGraphBentErrors(TGraph *theGraph, Option_t *option) void TGraphPainter::PaintGraphErrors(TGraph *theGraph, Option_t *option) { - Double_t *xline = 0; - Double_t *yline = 0; + std::vector xline, yline; Int_t if1 = 0; Int_t if2 = 0; Double_t xb[4], yb[4]; @@ -3451,9 +3438,9 @@ void TGraphPainter::PaintGraphErrors(TGraph *theGraph, Option_t *option) if (strchr(option,'5')) {option2 = kTRUE; option5 = kTRUE;} if (option3) { - xline = new Double_t[2*theNpoints]; - yline = new Double_t[2*theNpoints]; - if (!xline || !yline) { + xline.resize(2*theNpoints); + yline.resize(2*theNpoints); + if (xline.empty() || yline.empty()) { Error("Paint", "too many points, out of memory"); return; } @@ -3634,12 +3621,10 @@ void TGraphPainter::PaintGraphErrors(TGraph *theGraph, Option_t *option) Int_t logy = gPad->GetLogy(); gPad->SetLogx(0); gPad->SetLogy(0); - if (option4) PaintGraph(theGraph, 2*theNpoints, xline, yline,"FC"); - else PaintGraph(theGraph, 2*theNpoints, xline, yline,"F"); + if (option4) PaintGraph(theGraph, 2*theNpoints, xline.data(), yline.data(),"FC"); + else PaintGraph(theGraph, 2*theNpoints, xline.data(), yline.data(),"F"); gPad->SetLogx(logx); gPad->SetLogy(logy); - delete [] xline; - delete [] yline; } } @@ -3871,14 +3856,13 @@ void TGraphPainter::PaintGraphPolar(TGraph *theGraph, Option_t* options) if (TestBit(TH1::kNoTitle)) return; Int_t nt = strlen(theGraph->GetTitle()); - TPaveText *title = 0; - TObject *obj; + TPaveText *title = nullptr; TIter next(gPad->GetListOfPrimitives()); - while ((obj = next())) { + while (auto obj = next()) { if (!obj->InheritsFrom(TPaveText::Class())) continue; title = (TPaveText*)obj; if (title->GetName()) - if (strcmp(title->GetName(),"title")) {title = 0; continue;} + if (strcmp(title->GetName(),"title")) {title = nullptr; continue;} break; } if (nt == 0 || gStyle->GetOptTitle() <= 0) { @@ -4203,10 +4187,10 @@ void TGraphPainter::PaintPolyLineHatches(TGraph *theGraph, Int_t n, const Double Int_t i,j,nf; Double_t w = (theGraph->GetLineWidth()/100)*0.005; - Double_t *xf = new Double_t[2*n]; - Double_t *yf = new Double_t[2*n]; - Double_t *xt = new Double_t[n]; - Double_t *yt = new Double_t[n]; + std::vector xf(2*n); + std::vector yf(2*n); + std::vector xt(n); + std::vector yt(n); Double_t x1, x2, y1, y2, x3, y3, xm, ym, a, a1, a2, a3; // Compute the gPad coordinates in TRUE normalized space (NDC) @@ -4389,13 +4373,8 @@ void TGraphPainter::PaintPolyLineHatches(TGraph *theGraph, Int_t n, const Double } // Draw filled area - gPad->PaintFillArea(nf+1,xf,yf); + gPad->PaintFillArea(nf+1,xf.data(),yf.data()); theGraph->TAttLine::Modify(); // In case of PaintFillAreaHatches - - delete [] xf; - delete [] yf; - delete [] xt; - delete [] yt; } @@ -4406,11 +4385,10 @@ void TGraphPainter::PaintStats(TGraph *theGraph, TF1 *fit) { Int_t dofit; - TPaveStats *stats = 0; + TPaveStats *stats = nullptr; TList *functions = theGraph->GetListOfFunctions(); TIter next(functions); - TObject *obj; - while ((obj = next())) { + while (auto obj = next()) { if (obj->InheritsFrom(TPaveStats::Class())) { stats = (TPaveStats*)obj; break; @@ -4551,9 +4529,9 @@ void TGraphPainter::Smooth(TGraph *theGraph, Int_t npoints, Double_t *x, Double_ n2 = npointsMax-2; banksize = n2; - Double_t *qlx = new Double_t[npointsMax]; - Double_t *qly = new Double_t[npointsMax]; - if (!qlx || !qly) { + std::vector qlx(npointsMax); + std::vector qly(npointsMax); + if (qlx.empty() || qly.empty()) { Error("Smooth", "not enough space in memory"); return; } @@ -4928,16 +4906,13 @@ void TGraphPainter::Smooth(TGraph *theGraph, Int_t npoints, Double_t *x, Double_ if (npt < banksize) goto L320; if (drawtype >= 1000 || ktype > 1) { Int_t newsize = banksize + n2; - Double_t *qtemp = new Double_t[banksize]; + std::vector qtemp(banksize); for (i=0;i= 1000) { - gPad->PaintFillArea(npt,qlx,qly, "B"); + gPad->PaintFillArea(npt,qlx.data(),qly.data(), "B"); } else { if (ktype > 1) { if (!loptx) { @@ -4960,10 +4935,10 @@ void TGraphPainter::Smooth(TGraph *theGraph, Int_t npoints, Double_t *x, Double_ qly[npt] = qly[npt-1]; qly[npt+1] = qly[0]; } - gPad->PaintFillArea(npt+2,qlx,qly); + gPad->PaintFillArea(npt+2,qlx.data(),qly.data()); } - if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, qlx, qly); - gPad->PaintPolyLine(npt,qlx,qly); + if (TMath::Abs(theGraph->GetLineWidth())>99) PaintPolyLineHatches(theGraph, npt, qlx.data(), qly.data()); + gPad->PaintPolyLine(npt,qlx.data(),qly.data()); } npt = 1; qlx[0] = sxmin + xt/xratio; @@ -4982,8 +4957,6 @@ void TGraphPainter::Smooth(TGraph *theGraph, Int_t npoints, Double_t *x, Double_ y[i] = symin + y[i]/yratio; } - delete [] qlx; - delete [] qly; } //////////////////////////////////////////////////////////////////////////////// From d8b5dd8ca1c3d44bfce234e33359ea88a003c797 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Mon, 27 Jun 2022 16:39:02 +0200 Subject: [PATCH 038/104] Use 2D vector in TGraphPainter::PaintGraphMultiErrors Ensure correct cleanup of memory --- hist/histpainter/src/TGraphPainter.cxx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/hist/histpainter/src/TGraphPainter.cxx b/hist/histpainter/src/TGraphPainter.cxx index 653211881708e..84e97000e9ae1 100644 --- a/hist/histpainter/src/TGraphPainter.cxx +++ b/hist/histpainter/src/TGraphPainter.cxx @@ -2711,7 +2711,7 @@ void TGraphPainter::PaintGraphMultiErrors(TGraph *theGraph, Option_t *option) options[i] = ""; std::vector xline; - std::vector yline(NYErrors); + std::vector> yline(NYErrors); Int_t if1 = 0; Int_t if2 = 0; Double_t xb[4], yb[4]; @@ -2850,13 +2850,10 @@ void TGraphPainter::PaintGraphMultiErrors(TGraph *theGraph, Option_t *option) for (Int_t j = 0; j < NYErrors; j++) { if (Option3[j] && DrawErrors[j]) { - yline[j] = new Double_t[2 * NPointsInside]; + yline[j].resize(2 * NPointsInside); - if (!yline[j]) { + if (yline[j].empty()) { Error("PaintGraphMultiErrors", "too many points, out of memory"); - for (Int_t k = 0; k < j; k++) - if (yline[k]) - delete[] yline[k]; return; } } @@ -3109,7 +3106,7 @@ void TGraphPainter::PaintGraphMultiErrors(TGraph *theGraph, Option_t *option) tg->TAttLine::Copy(tgDummy); tg->TAttMarker::Copy(tgDummy); - for (Int_t j = 0; j < NYErrors; j++) { + for (Int_t j = 0; j < NYErrors; j++) if (Option3[j] && DrawErrors[j]) { if (IndividualStyles) { tg->GetAttFill(j)->Copy(tgDummy); @@ -3121,14 +3118,12 @@ void TGraphPainter::PaintGraphMultiErrors(TGraph *theGraph, Option_t *option) gPad->SetLogx(0); gPad->SetLogy(0); if (Option4[j]) - PaintGraph(&tgDummy, 2 * NPointsInside, xline.data(), yline[j], "FC"); + PaintGraph(&tgDummy, 2 * NPointsInside, xline.data(), yline[j].data(), "FC"); else - PaintGraph(&tgDummy, 2 * NPointsInside, xline.data(), yline[j], "F"); + PaintGraph(&tgDummy, 2 * NPointsInside, xline.data(), yline[j].data(), "F"); gPad->SetLogx(logx); gPad->SetLogy(logy); - delete[] yline[j]; } - } } From f5b3de94a4fbef55df59e0d3dbe4f3e143f7254a Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Mon, 27 Jun 2022 16:52:54 +0200 Subject: [PATCH 039/104] Use unique_ptr for highlight marker It is temporary object for painting of highlighted point in graph, never appears in list of primitives --- hist/histpainter/src/TGraphPainter.cxx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hist/histpainter/src/TGraphPainter.cxx b/hist/histpainter/src/TGraphPainter.cxx index 84e97000e9ae1..db7a49f1c44e7 100644 --- a/hist/histpainter/src/TGraphPainter.cxx +++ b/hist/histpainter/src/TGraphPainter.cxx @@ -37,13 +37,13 @@ #include "TRegexp.h" #include "strlcpy.h" #include "snprintf.h" -#include +#include Int_t TGraphPainter::fgMaxPointsPerLine = 50; static Int_t gHighlightPoint = -1; // highlight point of graph static TGraph *gHighlightGraph = nullptr; // pointer to graph with highlight point -static TMarker *gHighlightMarker = nullptr; // highlight marker +static std::unique_ptr gHighlightMarker; // highlight marker ClassImp(TGraphPainter); @@ -1128,7 +1128,7 @@ void TGraphPainter::SetHighlight(TGraph *theGraph) if (theGraph->IsHighlight()) return; // delete previous highlight marker - if (gHighlightMarker) { gHighlightMarker->Delete(); gHighlightMarker = nullptr; } + if (gHighlightMarker) gHighlightMarker.reset(nullptr); // emit Highlighted() signal (user can check on disabled) if (gPad->GetCanvas()) gPad->GetCanvas()->Highlighted(gPad, theGraph, gHighlightPoint, -1); } @@ -1175,7 +1175,7 @@ void TGraphPainter::PaintHighlightPoint(TGraph *theGraph, Option_t * /*option*/) Double_t hx, hy; if (theGraph->GetPoint(gHighlightPoint, hx, hy) == -1) { // special case, e.g. after interactive remove last point - if (gHighlightMarker) { gHighlightMarker->Delete(); gHighlightMarker = 0; } + if (gHighlightMarker) gHighlightMarker.reset(nullptr); return; } // testing specific possibility (after zoom, draw with "same", log, etc.) @@ -1195,7 +1195,7 @@ void TGraphPainter::PaintHighlightPoint(TGraph *theGraph, Option_t * /*option*/) if ((hy < uymin) || (hy > uymax)) return; if (!gHighlightMarker) { - gHighlightMarker = new TMarker(hx, hy, 24); + gHighlightMarker = std::make_unique(hx, hy, 24); gHighlightMarker->SetBit(kCannotPick); } gHighlightMarker->SetX(hx); @@ -1258,7 +1258,7 @@ void TGraphPainter::PaintHelper(TGraph *theGraph, Option_t *option) } // Paint the fit parameters if needed. - TF1 *fit = 0; + TF1 *fit = nullptr; TList *functions = theGraph->GetListOfFunctions(); TObject *f; if (functions) { @@ -2457,7 +2457,7 @@ void TGraphPainter::PaintGraphAsymmErrors(TGraph *theGraph, Option_t *option) Bool_t endLines = kTRUE; if (strchr(option,'z')) endLines = kFALSE; if (strchr(option,'Z')) endLines = kFALSE; - const char *arrowOpt = 0; + const char *arrowOpt = nullptr; if (strchr(option,'>')) arrowOpt = ">"; if (strstr(option,"|>")) arrowOpt = "|>"; @@ -3166,7 +3166,7 @@ void TGraphPainter::PaintGraphBentErrors(TGraph *theGraph, Option_t *option) Bool_t endLines = kTRUE; if (strchr(option,'z')) endLines = kFALSE; if (strchr(option,'Z')) endLines = kFALSE; - const char *arrowOpt = 0; + const char *arrowOpt = nullptr; if (strchr(option,'>')) arrowOpt = ">"; if (strstr(option,"|>")) arrowOpt = "|>"; @@ -3412,7 +3412,7 @@ void TGraphPainter::PaintGraphErrors(TGraph *theGraph, Option_t *option) Bool_t endLines = kTRUE; if (strchr(option,'z')) endLines = kFALSE; if (strchr(option,'Z')) endLines = kFALSE; - const char *arrowOpt = 0; + const char *arrowOpt = nullptr; if (strchr(option,'>')) arrowOpt = ">"; if (strstr(option,"|>")) arrowOpt = "|>"; From d8fe614b6cace1308f1077c7e960c17c417f8860 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Mon, 27 Jun 2022 17:12:37 +0200 Subject: [PATCH 040/104] Use std::vector for temp arrays in TGraph2DPainter --- hist/histpainter/src/TGraph2DPainter.cxx | 102 ++++++++--------------- 1 file changed, 36 insertions(+), 66 deletions(-) diff --git a/hist/histpainter/src/TGraph2DPainter.cxx b/hist/histpainter/src/TGraph2DPainter.cxx index a9d1706c069e7..b56bfb7e391d8 100644 --- a/hist/histpainter/src/TGraph2DPainter.cxx +++ b/hist/histpainter/src/TGraph2DPainter.cxx @@ -24,6 +24,7 @@ #include "TStyle.h" #include "Hoption.h" #include "TH1.h" +#include R__EXTERN TH1 *gCurrentHist; R__EXTERN Hoption_t Hoption; @@ -242,10 +243,10 @@ TList *TGraph2DPainter::GetContourList(Double_t contour) // Allocate space to store the segments. They cannot be more than the // number of triangles. Double_t xs0c, ys0c, xs1c, ys1c; - Double_t *xs0 = new Double_t[fNdt]; - Double_t *ys0 = new Double_t[fNdt]; - Double_t *xs1 = new Double_t[fNdt]; - Double_t *ys1 = new Double_t[fNdt]; + std::vector xs0(fNdt); + std::vector ys0(fNdt); + std::vector xs1(fNdt); + std::vector ys1(fNdt); for (i=0;iz2) {z2=fZ[p2]; x2=fX[p2]; y2=fY[p2]; i2=2;} if (i0==0 && i2==0) { Error("GetContourList", "wrong vertices ordering"); - delete [] xs0; - delete [] ys0; - delete [] xs1; - delete [] ys1; return nullptr; } else { i1 = 3-i2-i0; @@ -341,10 +338,6 @@ TList *TGraph2DPainter::GetContourList(Double_t contour) if (fZ[p[2]]>z2) {z2=fZ[p[2]]; x2=fX[p[2]]; y2=fY[p[2]]; i2=2;} if (i0==0 && i2==0) { Error("GetContourList", "wrong vertices ordering"); - delete [] xs0; - delete [] ys0; - delete [] xs1; - delete [] ys1; return nullptr; } else { i1 = 3-i2-i0; @@ -386,8 +379,8 @@ TList *TGraph2DPainter::GetContourList(Double_t contour) TList *list = new TList(); // list holding all the graphs - Int_t *segUsed = new Int_t[fNdt]; - for(i=0; i segUsed(fNdt); + for(i=0; iAdd(graph); npg = 0; } - delete [] xs0; - delete [] ys0; - delete [] xs1; - delete [] ys1; - delete [] segUsed; return list; } @@ -579,24 +567,18 @@ void TGraph2DPainter::PaintContour(Option_t * /*option*/) Int_t ndivz = TMath::Abs(ndiv); if (gCurrentHist->TestBit(TH1::kUserContour) == 0) gCurrentHist->SetContour(ndiv); - Int_t theColor; - TList *l; - TGraph *g; - TObject *obj; - Double_t c; - if (!fNdt) FindTriangles(); for (Int_t k=0; kGetContourLevelPad(k); - l = GetContourList(c); + Double_t c = gCurrentHist->GetContourLevelPad(k); + TList *l = GetContourList(c); TIter next(l); - while ((obj = next())) { + while (auto obj = next()) { if(obj->InheritsFrom(TGraph::Class()) ) { - g=(TGraph*)obj; + TGraph *g = (TGraph*)obj; g->SetLineWidth(fGraph2D->GetLineWidth()); g->SetLineStyle(fGraph2D->GetLineStyle()); - theColor = Int_t((k+0.99)*Float_t(ncolors)/Float_t(ndivz)); + Int_t theColor = Int_t((k+0.99)*Float_t(ncolors)/Float_t(ndivz)); g->SetLineColor(gStyle->GetColorPalette(theColor)); g->Paint("l"); } @@ -620,9 +602,9 @@ void TGraph2DPainter::PaintErrors(Option_t * /* option */) } Int_t it; - Double_t *xm = new Double_t[2]; - Double_t *ym = new Double_t[2]; - Double_t err =0; + Double_t xm[2]; + Double_t ym[2]; + Double_t err = 0; fGraph2D->SetLineStyle(fGraph2D->GetLineStyle()); fGraph2D->SetLineWidth(fGraph2D->GetLineWidth()); @@ -709,8 +691,6 @@ void TGraph2DPainter::PaintErrors(Option_t * /* option */) ym[1] = temp2[1]; gPad->PaintPolyLine(2,xm,ym); } - delete [] xm; - delete [] ym; } @@ -941,9 +921,9 @@ void TGraph2DPainter::PaintPolyMarker(Option_t *option) if (gCurrentHist->TestBit(TH1::kUserContour) == 0) gCurrentHist->SetContour(ndiv); } - Double_t *xm = new Double_t[fNpoints]; - Double_t *ym = new Double_t[fNpoints]; - Double_t *zm = new Double_t[fNpoints]; + std::vector xm(fNpoints); + std::vector ym(fNpoints); + std::vector zm(fNpoints); Double_t hzmin = gCurrentHist->GetMinimum(); Double_t hzmax = gCurrentHist->GetMaximum(); @@ -988,14 +968,14 @@ void TGraph2DPainter::PaintPolyMarker(Option_t *option) npd++; } if (markers0) { - PaintPolyMarker0(npd,xm,ym); + PaintPolyMarker0(npd,xm.data(),ym.data()); } else if (colors) { Int_t cols = fGraph2D->GetMarkerColor(); for (it=0; itSetMarkerColor(gStyle->GetColorPalette(theColor)); fGraph2D->TAttMarker::Modify(); - gPad->PaintPolyMarker(1,&xm[it],&ym[it]); + gPad->PaintPolyMarker(1,xm.data()+it,ym.data()+it); } fGraph2D->SetMarkerColor(cols); } else { @@ -1003,11 +983,8 @@ void TGraph2DPainter::PaintPolyMarker(Option_t *option) fGraph2D->SetMarkerSize(fGraph2D->GetMarkerSize()); fGraph2D->SetMarkerColor(fGraph2D->GetMarkerColor()); fGraph2D->TAttMarker::Modify(); - gPad->PaintPolyMarker(npd,xm,ym); + gPad->PaintPolyMarker(npd,xm.data(),ym.data()); } - delete [] xm; - delete [] ym; - delete [] zm; } @@ -1028,8 +1005,8 @@ void TGraph2DPainter::PaintPolyLine(Option_t * /* option */) Double_t Xeps = (fXmax - fXmin) * 0.0001; Double_t Yeps = (fYmax - fYmin) * 0.0001; - Double_t *xm = new Double_t[fNpoints]; - Double_t *ym = new Double_t[fNpoints]; + std::vector xm(fNpoints); + std::vector ym(fNpoints); Int_t npd = 0; for (it=0; itSetLineWidth(fGraph2D->GetLineWidth()); fGraph2D->SetLineColor(fGraph2D->GetLineColor()); fGraph2D->TAttLine::Modify(); - gPad->PaintPolyLine(npd,xm,ym); - delete [] xm; - delete [] ym; + gPad->PaintPolyLine(npd,xm.data(),ym.data()); } @@ -1103,8 +1078,8 @@ void TGraph2DPainter::PaintTriangles_old(Option_t *option) { Double_t x[4], y[4], temp1[3],temp2[3]; Int_t it,t[3]; - Int_t *order = 0; - Double_t *dist = 0; + std::vector order; + std::vector dist; TView *view = gPad->GetView(); if (!view) { @@ -1122,8 +1097,8 @@ void TGraph2DPainter::PaintTriangles_old(Option_t *option) // Define the grid levels drawn on the triangles. // The grid levels are aligned on the Z axis' main tick marks. - Int_t nblev=0; - Double_t *glev=0; + Int_t nblev = 0; + std::vector glev; if (!tri1 && !tri2 && !wire) { Int_t ndivz = gCurrentHist->GetZaxis()->GetNdivisions()%100; Int_t nbins; @@ -1145,7 +1120,7 @@ void TGraph2DPainter::PaintTriangles_old(Option_t *option) } // Define the grid levels nblev = nbins+1; - glev = new Double_t[nblev]; + glev.resize(nblev); for (Int_t i = 0; i < nblev; ++i) glev[i] = binLow+i*binWidth; } @@ -1165,8 +1140,8 @@ void TGraph2DPainter::PaintTriangles_old(Option_t *option) if (!fNdt) FindTriangles(); Double_t cp = TMath::Cos(view->GetLongitude()*TMath::Pi()/180.); Double_t sp = TMath::Sin(view->GetLongitude()*TMath::Pi()/180.); - order = new Int_t[fNdt]; - dist = new Double_t[fNdt]; + order.resize(fNdt); + dist.resize(fNdt); Double_t xd,yd; Int_t p, n, m; Bool_t o = kFALSE; @@ -1188,7 +1163,7 @@ void TGraph2DPainter::PaintTriangles_old(Option_t *option) o = kTRUE; } } - TMath::Sort(fNdt, dist, order, o); + TMath::Sort(fNdt, dist.data(), order.data(), o); // Draw the triangles and markers if requested fGraph2D->SetFillColor(fGraph2D->GetFillColor()); @@ -1224,7 +1199,7 @@ void TGraph2DPainter::PaintTriangles_old(Option_t *option) if (tri1 || tri2) PaintLevels(t,x,y); if (!tri1 && !tri2 && !wire) { gPad->PaintFillArea(3,x,y); - PaintLevels(t,x,y,nblev,glev); + PaintLevels(t,x,y,nblev,glev.data()); } if (!tri2) gPad->PaintPolyLine(4,x,y); if (markers) { @@ -1245,9 +1220,6 @@ void TGraph2DPainter::PaintTriangles_old(Option_t *option) fGraph2D->SetLineStyle(lst); fGraph2D->TAttLine::Modify(); fGraph2D->TAttFill::Modify(); - delete [] order; - delete [] dist; - if (glev) delete [] glev; } @@ -1277,7 +1249,7 @@ void TGraph2DPainter::PaintTriangles_new(Option_t *option) // Define the grid levels drawn on the triangles. // The grid levels are aligned on the Z axis' main tick marks. Int_t nblev=0; - Double_t *glev=0; + std::vector glev; if (!tri1 && !tri2 && !wire) { Int_t ndivz = gCurrentHist->GetZaxis()->GetNdivisions()%100; Int_t nbins; @@ -1299,7 +1271,7 @@ void TGraph2DPainter::PaintTriangles_new(Option_t *option) } // Define the grid levels nblev = nbins+1; - glev = new Double_t[nblev]; + glev.resize(nblev); for (Int_t i = 0; i < nblev; ++i) glev[i] = binLow+i*binWidth; } @@ -1382,7 +1354,7 @@ void TGraph2DPainter::PaintTriangles_new(Option_t *option) if (tri1 || tri2) PaintLevels(p,x,y); if (!tri1 && !tri2 && !wire) { gPad->PaintFillArea(3,x,y); - PaintLevels(p,x,y,nblev,glev); + PaintLevels(p,x,y,nblev,glev.data()); } if (!tri2) gPad->PaintPolyLine(4,x,y); if (markers) { @@ -1403,6 +1375,4 @@ void TGraph2DPainter::PaintTriangles_new(Option_t *option) fGraph2D->SetLineStyle(lst); fGraph2D->TAttLine::Modify(); fGraph2D->TAttFill::Modify(); - - if (glev) delete [] glev; } From 869602aef823f0ffe78a9d35b3c4a78b7d950ef9 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Mon, 27 Jun 2022 17:23:42 +0200 Subject: [PATCH 041/104] Check gPad before call gPad->GetView() Typically such checks are in the begin of painting methods --- hist/histpainter/src/TGraph2DPainter.cxx | 10 +++++----- hist/histpainter/src/TGraphPainter.cxx | 1 - hist/histpainter/src/THistPainter.cxx | 24 ++++++++++++------------ hist/histpainter/src/TPaletteAxis.cxx | 2 +- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/hist/histpainter/src/TGraph2DPainter.cxx b/hist/histpainter/src/TGraph2DPainter.cxx index b56bfb7e391d8..87b7b48aaf049 100644 --- a/hist/histpainter/src/TGraph2DPainter.cxx +++ b/hist/histpainter/src/TGraph2DPainter.cxx @@ -595,7 +595,7 @@ void TGraph2DPainter::PaintErrors(Option_t * /* option */) { Double_t temp1[3],temp2[3]; - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintErrors", "No TView in current pad"); return; @@ -898,7 +898,7 @@ void TGraph2DPainter::PaintPolyMarker(Option_t *option) { Double_t temp1[3],temp2[3]; - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintPolyMarker", "No TView in current pad"); return; @@ -995,7 +995,7 @@ void TGraph2DPainter::PaintPolyLine(Option_t * /* option */) { Double_t temp1[3],temp2[3]; - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintPolyLine", "No TView in current pad"); return; @@ -1081,7 +1081,7 @@ void TGraph2DPainter::PaintTriangles_old(Option_t *option) std::vector order; std::vector dist; - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintTriangles", "No TView in current pad"); return; @@ -1232,7 +1232,7 @@ void TGraph2DPainter::PaintTriangles_new(Option_t *option) Double_t x[4], y[4], temp1[3],temp2[3]; Int_t p[3]; - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintTriangles", "No TView in current pad"); return; diff --git a/hist/histpainter/src/TGraphPainter.cxx b/hist/histpainter/src/TGraphPainter.cxx index db7a49f1c44e7..f5b2f03a9bbec 100644 --- a/hist/histpainter/src/TGraphPainter.cxx +++ b/hist/histpainter/src/TGraphPainter.cxx @@ -16,7 +16,6 @@ #include "TPolyLine.h" #include "TPolyMarker.h" #include "TCanvas.h" -#include "TView.h" #include "TStyle.h" #include "TH1.h" #include "TF1.h" diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index 6d69242114033..eed9036898a86 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -6607,7 +6607,7 @@ void THistPainter::Paint2DErrors(Option_t *) fXbuf[2] = Hparam.zmin; fYbuf[2] = Hparam.zmax*(1. + gStyle->GetHistTopMargin()); fLego = std::make_unique(fXbuf.data(), fYbuf.data()); - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("Paint2DErrors", "no TView in current pad"); return; @@ -6990,7 +6990,7 @@ void THistPainter::PaintH3(Option_t *option) if (strstr(opt,"fb")) Hoption.FrontBox = 0; if (strstr(opt,"bb")) Hoption.BackBox = 0; - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) return; Double_t thedeg = 90 - gPad->GetTheta(); Double_t phideg = -90 - gPad->GetPhi(); @@ -7471,7 +7471,7 @@ void THistPainter::PaintH3Box(Int_t iopt) fLego = std::make_unique(fXbuf.data(), fYbuf.data()); // Set view - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintH3", "no TView in current pad"); return; @@ -7655,7 +7655,7 @@ void THistPainter::PaintH3BoxRaster() fLego = std::make_unique(fXbuf.data(), fYbuf.data()); // Set view - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintH3", "no TView in current pad"); return; @@ -7857,7 +7857,7 @@ void THistPainter::PaintH3Iso() fLego = std::make_unique(fXbuf.data(), fYbuf.data()); - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintH3Iso", "no TView in current pad"); return; @@ -8037,7 +8037,7 @@ void THistPainter::PaintLego(Option_t *) // Now ready to draw the lego plot Int_t irep = 0; - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintLego", "no TView in current pad"); return; @@ -8150,7 +8150,7 @@ void THistPainter::PaintLegoAxis(TGaxis *axis, Double_t ang) Int_t ix1, ix2, iy1, iy2, iz1, iz2; Double_t rad; - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintLegoAxis", "no TView in current pad"); return; @@ -8323,7 +8323,7 @@ void THistPainter::PaintLegoAxis(TGaxis *axis, Double_t ang) void THistPainter::PaintPalette() { TPaletteAxis *palette = (TPaletteAxis*)fFunctions->FindObject("palette"); - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (palette) { if (view) { if (!palette->TestBit(TPaletteAxis::kHasView)) { @@ -9245,7 +9245,7 @@ void THistPainter::PaintSurface(Option_t *) // Now ready to draw the surface plot - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintSurface", "no TView in current pad"); return; @@ -9423,7 +9423,7 @@ void THistPainter::PaintTriangles(Option_t *option) // Define the 3D view if (Hparam.zmin == 0 && Hparam.zmax == 0) {Hparam.zmin = -1; Hparam.zmax = 1;} if (Hoption.Same) { - TView *viewsame = gPad->GetView(); + TView *viewsame = gPad ? gPad->GetView() : nullptr; if (!viewsame) { Error("PaintTriangles", "no TView in current pad, do not use option SAME"); return; @@ -9447,7 +9447,7 @@ void THistPainter::PaintTriangles(Option_t *option) } fLego = std::make_unique(fXbuf.data(), fYbuf.data()); - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintTriangles", "no TView in current pad"); return; @@ -10068,7 +10068,7 @@ void THistPainter::PaintTF3() fLego = std::make_unique(fXbuf.data(), fYbuf.data()); - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (!view) { Error("PaintTF3", "no TView in current pad"); return; diff --git a/hist/histpainter/src/TPaletteAxis.cxx b/hist/histpainter/src/TPaletteAxis.cxx index 0c3eb75f2c9ba..3ce0094817bcd 100644 --- a/hist/histpainter/src/TPaletteAxis.cxx +++ b/hist/histpainter/src/TPaletteAxis.cxx @@ -584,7 +584,7 @@ void TPaletteAxis::SavePrimitive(std::ostream &out, Option_t * /*= ""*/) void TPaletteAxis::UnZoom() { - TView *view = gPad->GetView(); + TView *view = gPad ? gPad->GetView() : nullptr; if (view) { delete view; gPad->SetView(nullptr); From b0a386dcaaa26f70f6d1a31ac93efa1877815005 Mon Sep 17 00:00:00 2001 From: Enrico Guiraud Date: Mon, 27 Jun 2022 21:22:36 +0200 Subject: [PATCH 042/104] [DF] Make const method const --- tree/dataframe/inc/ROOT/RDF/RInterface.hxx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tree/dataframe/inc/ROOT/RDF/RInterface.hxx b/tree/dataframe/inc/ROOT/RDF/RInterface.hxx index f9c2cf96d1d56..a7945f8f87468 100644 --- a/tree/dataframe/inc/ROOT/RDF/RInterface.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RInterface.hxx @@ -2756,10 +2756,7 @@ public: /// variations.Print(); /// ~~~ /// - RVariationsDescription GetVariations() - { - return {fColRegister.GetVariations()}; - } + RVariationsDescription GetVariations() const { return {fColRegister.GetVariations()}; } /// \brief Checks if a column is present in the dataset. /// \return true if the column is available, false otherwise From 02b6e5994df94e082815b2d171cc386120bd8c73 Mon Sep 17 00:00:00 2001 From: Enrico Guiraud Date: Mon, 27 Jun 2022 23:15:58 +0200 Subject: [PATCH 043/104] [NFC][DF] Improve data member docs --- tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx b/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx index d55f09c6c6d76..c219c5c5d93b3 100644 --- a/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx @@ -56,7 +56,8 @@ class RColumnRegister { std::shared_ptr> fAliases; /// Immutable multimap of Variations, can be shared among several nodes. /// The key is the name of an existing column, the values are all variations that affect that column. - /// As a consequence, Variations that affect multiple columns are inserted multiple times, once per column. + /// Variations that affect multiple columns are inserted in the map multiple times, once per column, + /// and conversely each column (i.e. each key) can have several associated variations. std::shared_ptr fVariations; std::shared_ptr fColumnNames; ///< Names of Defines and Aliases registered so far. From c6a2f50d4695ee97a025b8c2536737ff7ae54166 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Sat, 25 Jun 2022 10:38:18 +0200 Subject: [PATCH 044/104] [RF] Remove more dead HistFactory code in HistoToWorkspaceFactoryFast The HistoToWorkspaceFactoryFast has three unused private member functions that can be removed: * AddMultiVarGaussConstraint * AddPoissonTerms * EditSyst Removing this code makes it easier to figure out where the systematic constraint terms are actually created. --- .../HistFactory/HistoToWorkspaceFactoryFast.h | 14 - .../src/HistoToWorkspaceFactoryFast.cxx | 305 ------------------ 2 files changed, 319 deletions(-) diff --git a/roofit/histfactory/inc/RooStats/HistFactory/HistoToWorkspaceFactoryFast.h b/roofit/histfactory/inc/RooStats/HistFactory/HistoToWorkspaceFactoryFast.h index 75c67faa3c716..ddb1e0491f2ec 100644 --- a/roofit/histfactory/inc/RooStats/HistFactory/HistoToWorkspaceFactoryFast.h +++ b/roofit/histfactory/inc/RooStats/HistFactory/HistoToWorkspaceFactoryFast.h @@ -76,20 +76,6 @@ namespace RooStats{ std::unique_ptr CreateNormFactor(RooWorkspace* proto, std::string& channel, std::string& sigmaEpsilon, Sample& sample, bool doRatio); - void AddMultiVarGaussConstraint(RooWorkspace* proto, std::string prefix, - int lowBin, int highBin, - std::vector& likelihoodTermNames); - - void AddPoissonTerms(RooWorkspace* proto, std::string prefix, std::string obsPrefix, - std::string expPrefix, int lowBin, int highBin, - std::vector& likelihoodTermNames); - - static void EditSyst(RooWorkspace* proto, const char* pdfNameChar, - std::map gammaSyst, - std::map uniformSyst, - std::map logNormSyst, - std::map noSyst); - RooWorkspace* MakeSingleChannelWorkspace(Measurement& measurement, Channel& channel); void MakeTotalExpected(RooWorkspace* proto, const std::string& totName, diff --git a/roofit/histfactory/src/HistoToWorkspaceFactoryFast.cxx b/roofit/histfactory/src/HistoToWorkspaceFactoryFast.cxx index 5574ae911e7e5..07b80196b6b68 100644 --- a/roofit/histfactory/src/HistoToWorkspaceFactoryFast.cxx +++ b/roofit/histfactory/src/HistoToWorkspaceFactoryFast.cxx @@ -711,313 +711,8 @@ RooArgList HistoToWorkspaceFactoryFast::createObservables(const TH1 *hist, RooWo proto->import(tot, RecycleConflictNodes()); } - void HistoToWorkspaceFactoryFast::AddPoissonTerms(RooWorkspace* proto, string prefix, string obsPrefix, string expPrefix, int lowBin, int highBin, - vector& likelihoodTermNames){ - ///////////////////////////////// - // Relate observables to expected for each bin - // later modify variable named expPrefix_i to be product of terms - RooArgSet Pois(prefix.c_str()); - for(Int_t i=lowBin; ifactory(command); - - // output - cout << "Poisson Term " << command << endl; - ((RooAbsPdf*) temp)->setEvalErrorLoggingMode(RooAbsReal::PrintErrors); - //cout << temp << endl; - - likelihoodTermNames.push_back( temp->GetName() ); - Pois.add(* temp ); - } - proto->defineSet(prefix.c_str(),Pois); // add argset to workspace - } - ////////////////////////////////////////////////////////////////////////////// - void HistoToWorkspaceFactoryFast::EditSyst(RooWorkspace* proto, const char* pdfNameChar, - map gammaSyst, - map uniformSyst, - map logNormSyst, - map noSyst) { - string pdfName(pdfNameChar); - - ModelConfig * combined_config = (ModelConfig *) proto->obj("ModelConfig"); - if( combined_config==nullptr ) { - std::cout << "Error: Failed to find object 'ModelConfig' in workspace: " - << proto->GetName() << std::endl; - throw hf_exc(); - } - // const RooArgSet * constrainedParams=combined_config->GetNuisanceParameters(); - // RooArgSet temp(*constrainedParams); - string edit="EDIT::newSimPdf("+pdfName+","; - string editList; - string lastPdf=pdfName; - string precede=""; - unsigned int numReplacements = 0; - unsigned int nskipped = 0; - map::iterator it; - - - // add gamma terms and their constraints - for(it=gammaSyst.begin(); it!=gammaSyst.end(); ++it) { - //cout << "edit for " << it->first << "with rel uncert = " << it->second << endl; - if(! proto->var("alpha_"+it->first)){ - //cout << "systematic not there" << endl; - nskipped++; - continue; - } - numReplacements++; - - double relativeUncertainty = it->second; - double scale = 1/sqrt((1+1/pow(relativeUncertainty,2))); - - // this is the Gamma PDF and in a form that doesn't have roundoff problems like the Poisson does - proto->factory("beta_" + it->first + "[1,0,10]"); - proto->factory(Form("y_%s[%f]",it->first.c_str(),1./pow(relativeUncertainty,2))) ; - proto->factory(Form("theta_%s[%f]",it->first.c_str(),pow(relativeUncertainty,2))) ; - proto->factory(Form("Gamma::beta_%sConstraint(beta_%s,sum::k_%s(y_%s,one[1]),theta_%s,zero[0])", - it->first.c_str(), - it->first.c_str(), - it->first.c_str(), - it->first.c_str(), - it->first.c_str())) ; - - /* - // this has some problems because N in poisson is rounded to nearest integer - proto->factory(Form("Poisson::beta_%sConstraint(y_%s[%f],prod::taub_%s(taus_%s[%f],beta_%s[1,0,5]))", - it->first.c_str(), - it->first.c_str(), - 1./pow(relativeUncertainty,2), - it->first.c_str(), - it->first.c_str(), - 1./pow(relativeUncertainty,2), - it->first.c_str() - ) ) ; - */ - // combined->factory(Form("expr::alphaOfBeta('(beta-1)/%f',beta)",scale)); - // combined->factory(Form("expr::alphaOfBeta_%s('(beta_%s-1)/%f',beta_%s)",it->first.c_str(),it->first.c_str(),scale,it->first.c_str())); - proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",it->first.c_str(),it->first.c_str(),-1./scale,1./scale)); - - // set beta const status to be same as alpha - if(proto->var("alpha_" + it->first)->isConstant()) { - proto->var("beta_" + it->first)->setConstant(true); - } - else { - proto->var("beta_" + it->first)->setConstant(false); - } - // set alpha const status to true - // proto->var("alpha_" + it->first)->setConstant(true); - - // replace alphas with alphaOfBeta and replace constraints - editList+=precede + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint"; - precede=","; - editList+=precede + "alpha_"+it->first+"=alphaOfBeta_"+ it->first; - - /* - if( proto->pdf("alpha_"+it->first+"Constraint") && proto->var("alpha_"+it->first) - cout << " checked they are there" << proto->pdf("alpha_"+it->first+"Constraint") << " " << proto->var("alpha_"+it->first) << endl; - else - cout << "NOT THERE" << endl; - */ - - // EDIT seems to die if the list of edits is too long. So chunck them up. - if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){ - edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")"; - lastPdf+="_"; // append an underscore for the edit - editList=""; // reset edit list - precede=""; - cout << "Going to issue this edit command\n" << edit<< endl; - proto->factory(edit); - RooAbsPdf* newOne = proto->pdf(lastPdf); - if(!newOne) - cxcoutWHF << "---------------------\n WARNING: failed to make EDIT\n\n" << endl; - - } - } - - // add uniform terms and their constraints - for(it=uniformSyst.begin(); it!=uniformSyst.end(); ++it) { - cout << "edit for " << it->first << "with rel uncert = " << it->second << endl; - if(! proto->var("alpha_"+it->first)){ - cout << "systematic not there" << endl; - nskipped++; - continue; - } - numReplacements++; - - // this is the Uniform PDF - proto->factory("beta_" + it->first + "[1,0,10]"); - proto->factory(Form("Uniform::beta_%sConstraint(beta_%s)",it->first.c_str(),it->first.c_str())); - proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{-1,1})",it->first.c_str(),it->first.c_str())); - - // set beta const status to be same as alpha - if(proto->var("alpha_" + it->first)->isConstant()) - proto->var("beta_" + it->first)->setConstant(true); - else - proto->var("beta_" + it->first)->setConstant(false); - // set alpha const status to true - // proto->var("alpha_" + it->first)->setConstant(true); - - // replace alphas with alphaOfBeta and replace constraints - cout << "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint" << endl; - editList+=precede + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint"; - precede=","; - cout << "alpha_"+it->first+"=alphaOfBeta_"+ it->first << endl; - editList+=precede + "alpha_"+it->first+"=alphaOfBeta_"+ it->first; - - if( proto->pdf("alpha_"+it->first+"Constraint") && proto->var("alpha_"+it->first)) - cout << " checked they are there" << proto->pdf("alpha_"+it->first+"Constraint") << " " << proto->var("alpha_"+it->first) << endl; - else - cout << "NOT THERE" << endl; - - // EDIT seems to die if the list of edits is too long. So chunck them up. - if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){ - edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")"; - lastPdf+="_"; // append an underscore for the edit - editList=""; // reset edit list - precede=""; - cout << edit<< endl; - proto->factory(edit); - RooAbsPdf* newOne = proto->pdf(lastPdf); - if(!newOne) - cxcoutWHF << "---------------------\n WARNING: failed to make EDIT\n\n" << endl; - - } - } - - ///////////////////////////////////////// - //////////////////////////////////// - - - // add lognormal terms and their constraints - for(it=logNormSyst.begin(); it!=logNormSyst.end(); ++it) { - cout << "edit for " << it->first << "with rel uncert = " << it->second << endl; - if(! proto->var("alpha_"+it->first)){ - cout << "systematic not there" << endl; - nskipped++; - continue; - } - numReplacements++; - - double relativeUncertainty = it->second; - double kappa = 1+relativeUncertainty; - // when transforming beta -> alpha, need alpha=1 to be +1sigma value. - // the P(beta>kappa*\hat(beta)) = 16% - // and \hat(beta) is 1, thus - double scale = relativeUncertainty; - //double scale = kappa; - - const char * cname = it->first.c_str(); - - // this is the LogNormal - proto->factory(TString::Format("beta_%s[1,0,10]",cname)); - proto->factory(TString::Format("nom_beta_%s[1]",cname)); - proto->factory(TString::Format("kappa_%s[%f]",cname,kappa)); - proto->factory(TString::Format("Lognormal::beta_%sConstraint(beta_%s,nom_beta_%s,kappa_%s)", - cname, cname, cname, cname)) ; - proto->factory(TString::Format("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",cname,cname,-1./scale,1./scale)); - - - // set beta const status to be same as alpha - if(proto->var(TString::Format("alpha_%s",cname))->isConstant()) - proto->var(TString::Format("beta_%s",cname))->setConstant(true); - else - proto->var(TString::Format("beta_%s",cname))->setConstant(false); - // set alpha const status to true - // proto->var(TString::Format("alpha_%s",cname))->setConstant(true); - - // replace alphas with alphaOfBeta and replace constraints - cout << "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint" << endl; - editList+=precede + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint"; - precede=","; - cout << "alpha_"+it->first+"=alphaOfBeta_"+ it->first << endl; - editList+=precede + "alpha_"+it->first+"=alphaOfBeta_"+ it->first; - - if( proto->pdf("alpha_"+it->first+"Constraint") && proto->var("alpha_"+it->first) ) - cout << " checked they are there" << proto->pdf("alpha_"+it->first+"Constraint") << " " << proto->var("alpha_"+it->first) << endl; - else - cout << "NOT THERE" << endl; - - // EDIT seems to die if the list of edits is too long. So chunck them up. - if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){ - edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")"; - lastPdf+="_"; // append an underscore for the edit - editList=""; // reset edit list - precede=""; - cout << edit<< endl; - proto->factory(edit); - RooAbsPdf* newOne = proto->pdf(lastPdf); - if(!newOne) - cxcoutWHF << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl; - - } - // add global observables - const RooArgSet * gobs = proto->set("globalObservables"); - RooArgSet gobsNew(*gobs); - gobsNew.add(*proto->var(TString::Format("nom_beta_%s",cname)) ); - proto->removeSet("globalObservables"); - proto->defineSet("globalObservables",gobsNew); - gobsNew.Print(); - - } - - ///////////////////////////////////////// - - // MB: remove a systematic constraint - for(it=noSyst.begin(); it!=noSyst.end(); ++it) { - - cout << "remove constraint for parameter" << it->first << endl; - if(! proto->var("alpha_"+it->first) || ! proto->pdf("alpha_"+it->first+"Constraint") ) { - cout << "systematic not there" << endl; - nskipped++; - continue; - } - numReplacements++; - - // dummy replacement pdf - if ( !proto->var("one") ) { proto->factory("one[1.0]"); } - proto->var("one")->setConstant(); - - // replace constraints - cout << "alpha_"+it->first+"Constraint=one" << endl; - editList+=precede + "alpha_"+it->first+"Constraint=one"; - precede=","; - - // EDIT seems to die if the list of edits is too long. So chunck them up. - if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){ - edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")"; - lastPdf+="_"; // append an underscore for the edit - editList=""; // reset edit list - precede=""; - cout << edit << endl; - proto->factory(edit); - RooAbsPdf* newOne = proto->pdf(lastPdf); - if(!newOne) { - cxcoutWHF << "---------------------\n WARNING: failed to make EDIT\n\n" << endl; - } - } - } - - ///////////////////////////////////////// - - // commit last bunch of edits - edit="EDIT::newSimPdf("+lastPdf+","+editList+")"; - cout << edit<< endl; - proto->factory(edit); - // proto->writeToFile(("results/model_"+fRowTitle+"_edited.root").c_str()); - RooAbsPdf* newOne = proto->pdf("newSimPdf"); - if(newOne){ - // newOne->graphVizTree(("results/"+pdfName+"_"+fRowTitle+"newSimPdf.dot").c_str()); - combined_config->SetPdf(*newOne); - } - else{ - cxcoutWHF << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl; - } - } - void HistoToWorkspaceFactoryFast::PrintCovarianceMatrix(RooFitResult* result, RooArgSet* params, string filename){ FILE* covFile = fopen ((filename).c_str(),"w"); From 9a5cca1a5bef90f8995324d3fab8a2f500dcc39a Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Sat, 18 Jun 2022 10:38:43 +0200 Subject: [PATCH 045/104] [RF] Avoid some code duplication in RooRealSumFunc/RooRealSumPdf Some functions in RooRealSumFunc and RooRealSumPdf are overloaded in exactly the same way, for example `evaluate` and `checkObservables`. To avoid code duplication, they are implemented also as private static functions in RooRealSumPdf, which the friend class RooRealSumFunc can also use. This pattern might be used also to avoid further code duplication, also with the other addition classes like RooAddition and RooAddPdf. --- roofit/roofitcore/inc/RooRealSumFunc.h | 1 + roofit/roofitcore/inc/RooRealSumPdf.h | 11 +++ roofit/roofitcore/src/RooRealSumFunc.cxx | 88 ++---------------------- roofit/roofitcore/src/RooRealSumPdf.cxx | 76 +++++++++++--------- 4 files changed, 62 insertions(+), 114 deletions(-) diff --git a/roofit/roofitcore/inc/RooRealSumFunc.h b/roofit/roofitcore/inc/RooRealSumFunc.h index 453807526ad0d..86a815f6dea6f 100644 --- a/roofit/roofitcore/inc/RooRealSumFunc.h +++ b/roofit/roofitcore/inc/RooRealSumFunc.h @@ -83,6 +83,7 @@ class RooRealSumFunc : public RooAbsReal { RooListProxy _coefList; ///< List of coefficients bool _doFloor; ///< Introduce floor at zero in pdf + mutable bool _haveWarned{false}; /// #include @@ -178,89 +177,14 @@ RooRealSumFunc::~RooRealSumFunc() //_____________________________________________________________________________ double RooRealSumFunc::evaluate() const { - // Calculate the current value - - double value(0); - - // Do running sum of coef/func pairs, calculate lastCoef. - RooFIter funcIter = _funcList.fwdIterator(); - RooFIter coefIter = _coefList.fwdIterator(); - RooAbsReal *coef; - RooAbsReal *func; - - // N funcs, N-1 coefficients - double lastCoef(1); - while ((coef = (RooAbsReal *)coefIter.next())) { - func = (RooAbsReal *)funcIter.next(); - double coefVal = coef->getVal(); - if (coefVal) { - cxcoutD(Eval) << "RooRealSumFunc::eval(" << GetName() << ") coefVal = " << coefVal - << " funcVal = " << func->ClassName() << "::" << func->GetName() << " = " << func->getVal() - << endl; - if (func->isSelectedComp()) { - value += func->getVal() * coefVal; - } - lastCoef -= coef->getVal(); - } - } - - if (!_haveLastCoef) { - // Add last func with correct coefficient - func = (RooAbsReal *)funcIter.next(); - if (func->isSelectedComp()) { - value += func->getVal() * lastCoef; - } - - cxcoutD(Eval) << "RooRealSumFunc::eval(" << GetName() << ") lastCoef = " << lastCoef - << " funcVal = " << func->getVal() << endl; - - // Warn about coefficient degeneration - if (lastCoef < 0 || lastCoef > 1) { - coutW(Eval) << "RooRealSumFunc::evaluate(" << GetName() - << " WARNING: sum of FUNC coefficients not in range [0-1], value=" << 1 - lastCoef << endl; - } - } - - // Introduce floor if so requested - if (value < 0 && (_doFloor || _doFloorGlobal)) { - value = 0; - } - - return value; + return RooRealSumPdf::evaluate(*this, _funcList, _coefList, _doFloor || _doFloorGlobal, _haveWarned); } //_____________________________________________________________________________ bool RooRealSumFunc::checkObservables(const RooArgSet *nset) const { - // Check if FUNC is valid for given normalization set. - // Coeffient and FUNC must be non-overlapping, but func-coefficient - // pairs may overlap each other - // - // In the present implementation, coefficients may not be observables or derive - // from observables - - bool ret(false); - - for (unsigned int i=0; i < _coefList.size(); ++i) { - const auto& coef = _coefList[i]; - const auto& func = _funcList[i]; - - if (func.observableOverlaps(nset, coef)) { - coutE(InputArguments) << "RooRealSumFunc::checkObservables(" << GetName() << "): ERROR: coefficient " - << coef.GetName() << " and FUNC " << func.GetName() - << " have one or more observables in common" << endl; - ret = true; - } - if (coef.dependsOn(*nset)) { - coutE(InputArguments) << "RooRealPdf::checkObservables(" << GetName() << "): ERROR coefficient " - << coef.GetName() << " depends on one or more of the following observables"; - nset->Print("1"); - ret = true; - } - } - - return ret; + return RooRealSumPdf::checkObservables(*this, nset, _funcList, _coefList); } //_____________________________________________________________________________ diff --git a/roofit/roofitcore/src/RooRealSumPdf.cxx b/roofit/roofitcore/src/RooRealSumPdf.cxx index 98bb12cc65169..18f4653fb64ac 100644 --- a/roofit/roofitcore/src/RooRealSumPdf.cxx +++ b/roofit/roofitcore/src/RooRealSumPdf.cxx @@ -214,28 +214,28 @@ RooAbsPdf::ExtendMode RooRealSumPdf::extendMode() const } - - -//////////////////////////////////////////////////////////////////////////////// -/// Calculate the current value - -double RooRealSumPdf::evaluate() const +double RooRealSumPdf::evaluate(RooAbsReal const& caller, + RooArgList const& funcList, + RooArgList const& coefList, + bool doFloor, + bool & hasWarnedBefore) { // Do running sum of coef/func pairs, calculate lastCoef. double value = 0; double sumCoeff = 0.; - for (unsigned int i = 0; i < _funcList.size(); ++i) { - const auto func = static_cast(&_funcList[i]); - const auto coef = static_cast(i < _coefList.size() ? &_coefList[i] : nullptr); + for (unsigned int i = 0; i < funcList.size(); ++i) { + const auto func = static_cast(&funcList[i]); + const auto coef = static_cast(i < coefList.size() ? &coefList[i] : nullptr); const double coefVal = coef != nullptr ? coef->getVal() : (1. - sumCoeff); // Warn about degeneration of last coefficient if (coef == nullptr && (coefVal < 0 || coefVal > 1.)) { - if (!_haveWarned) { - coutW(Eval) << "RooRealSumPdf::evaluate(" << GetName() + if (!hasWarnedBefore) { + oocoutW(&caller, Eval) << caller.ClassName() << "::evaluate(" << caller.GetName() << ") WARNING: sum of FUNC coefficients not in range [0-1], value=" - << sumCoeff << ". This means that the PDF is not properly normalised. If the PDF was meant to be extended, provide as many coefficients as functions." << endl ; - _haveWarned = true; + << sumCoeff << ". This means that the PDF is not properly normalised." + << " If the PDF was meant to be extended, provide as many coefficients as functions." << std::endl; + hasWarnedBefore = true; } // Signal that we are in an undefined region: value = RooNaNPacker::packFloatIntoNaN(100.f * (coefVal < 0. ? -coefVal : coefVal - 1.)); @@ -249,11 +249,16 @@ double RooRealSumPdf::evaluate() const } // Introduce floor if so requested - if (value<0 && (_doFloor || _doFloorGlobal)) { - value = 0 ; - } + return value < 0 && doFloor ? 0.0 : value; +} + - return value ; +//////////////////////////////////////////////////////////////////////////////// +/// Calculate the current value + +double RooRealSumPdf::evaluate() const +{ + return evaluate(*this, _funcList, _coefList, _doFloor || _doFloorGlobal, _haveWarned); } @@ -306,29 +311,24 @@ void RooRealSumPdf::computeBatch(cudaStream_t* /*stream*/, double* output, size_ } -//////////////////////////////////////////////////////////////////////////////// -/// Check if FUNC is valid for given normalization set. -/// Coefficient and FUNC must be non-overlapping, but func-coefficient -/// pairs may overlap each other. -/// -/// In the present implementation, coefficients may not be observables or derive -/// from observables. - -bool RooRealSumPdf::checkObservables(const RooArgSet* nset) const +bool RooRealSumPdf::checkObservables(RooAbsReal const& caller, RooArgSet const* nset, + RooArgList const& funcList, RooArgList const& coefList) { bool ret(false) ; - for (unsigned int i=0; i < _coefList.size(); ++i) { - const auto& coef = _coefList[i]; - const auto& func = _funcList[i]; + for (unsigned int i=0; i < coefList.size(); ++i) { + const auto& coef = coefList[i]; + const auto& func = funcList[i]; if (func.observableOverlaps(nset, coef)) { - coutE(InputArguments) << "RooRealSumPdf::checkObservables(" << GetName() << "): ERROR: coefficient " << coef.GetName() - << " and FUNC " << func.GetName() << " have one or more observables in common" << endl ; + oocoutE(&caller, InputArguments) << caller.ClassName() << "::checkObservables(" << caller.GetName() + << "): ERROR: coefficient " << coef.GetName() + << " and FUNC " << func.GetName() << " have one or more observables in common" << std::endl; ret = true ; } if (coef.dependsOn(*nset)) { - coutE(InputArguments) << "RooRealPdf::checkObservables(" << GetName() << "): ERROR coefficient " << coef.GetName() + oocoutE(&caller, InputArguments) << caller.ClassName() << "::checkObservables(" << caller.GetName() + << "): ERROR coefficient " << coef.GetName() << " depends on one or more of the following observables" ; nset->Print("1") ; ret = true ; } @@ -338,6 +338,18 @@ bool RooRealSumPdf::checkObservables(const RooArgSet* nset) const } +//////////////////////////////////////////////////////////////////////////////// +/// Check if FUNC is valid for given normalization set. +/// Coefficient and FUNC must be non-overlapping, but func-coefficient +/// pairs may overlap each other. +/// +/// In the present implementation, coefficients may not be observables or derive +/// from observables. + +bool RooRealSumPdf::checkObservables(const RooArgSet* nset) const +{ + return checkObservables(*this, nset, _funcList, _coefList); +} //////////////////////////////////////////////////////////////////////////////// From 60b95a943d2c8432549c8555c641dc770139eb3e Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 27 Jun 2022 22:27:36 +0200 Subject: [PATCH 046/104] [RF] Avoid some code duplication in RooRealSumFunc/RooRealSumPdf part 2 This continues the work from the previous commit and should be squashed with it on merge. --- roofit/roofitcore/inc/RooRealSumFunc.h | 20 +- roofit/roofitcore/inc/RooRealSumPdf.h | 17 +- roofit/roofitcore/src/RooRealSumFunc.cxx | 279 +---------------------- roofit/roofitcore/src/RooRealSumPdf.cxx | 104 ++++++--- 4 files changed, 100 insertions(+), 320 deletions(-) diff --git a/roofit/roofitcore/inc/RooRealSumFunc.h b/roofit/roofitcore/inc/RooRealSumFunc.h index 86a815f6dea6f..7190a39667deb 100644 --- a/roofit/roofitcore/inc/RooRealSumFunc.h +++ b/roofit/roofitcore/inc/RooRealSumFunc.h @@ -16,10 +16,12 @@ #ifndef ROO_REAL_SUM_FUNC #define ROO_REAL_SUM_FUNC +#include "RooRealSumPdf.h" #include "RooAbsPdf.h" #include "RooListProxy.h" #include "RooAICRegistry.h" #include "RooObjCacheManager.h" + #include class RooRealSumFunc : public RooAbsReal { @@ -62,19 +64,7 @@ class RooRealSumFunc : public RooAbsReal { } protected: - class CacheElem : public RooAbsCacheElement { - public: - CacheElem(){}; - ~CacheElem() override{}; - RooArgList containedArgs(Action) override - { - RooArgList ret(_funcIntList); - ret.add(_funcNormList); - return ret; - } - RooArgList _funcIntList; - RooArgList _funcNormList; - }; + using CacheElem = RooRealSumPdf::CacheElem; mutable RooObjCacheManager _normIntMgr; //! The integration cache manager bool _haveLastCoef; @@ -82,9 +72,9 @@ class RooRealSumFunc : public RooAbsReal { RooListProxy _funcList; ///< List of component FUNCs RooListProxy _coefList; ///< List of coefficients - bool _doFloor; ///< Introduce floor at zero in pdf + bool _doFloor = false; ///< Introduce floor at zero in pdf mutable bool _haveWarned{false}; ///* binBoundaries( + RooArgList const& funcList, RooAbsRealLValue& /*obs*/, double /*xlo*/, double /*xhi*/); + static std::list* plotSamplingHint( + RooArgList const& funcList, RooAbsRealLValue& /*obs*/, double /*xlo*/, double /*xhi*/); + + static void printMetaArgs(RooArgList const& funcList, RooArgList const& coefList, std::ostream& os); ClassDefOverride(RooRealSumPdf, 5) // PDF constructed from a sum of (non-pdf) functions }; diff --git a/roofit/roofitcore/src/RooRealSumFunc.cxx b/roofit/roofitcore/src/RooRealSumFunc.cxx index cfabd8c744f5c..4f271a8a28780 100644 --- a/roofit/roofitcore/src/RooRealSumFunc.cxx +++ b/roofit/roofitcore/src/RooRealSumFunc.cxx @@ -35,9 +35,6 @@ #include "RooRealSumFunc.h" -#include "RooRealSumPdf.h" -#include "RooRealProxy.h" -#include "RooPlot.h" #include "RooRealVar.h" #include "RooAddGenContext.h" #include "RooRealConstant.h" @@ -48,11 +45,8 @@ #include "Riostream.h" -#include #include -using namespace std; - ClassImp(RooRealSumFunc); bool RooRealSumFunc::_doFloorGlobal = false; @@ -62,15 +56,13 @@ RooRealSumFunc::RooRealSumFunc() : _normIntMgr(this, 10) { // Default constructor // coverity[UNINIT_CTOR] - _doFloor = false; TRACE_CREATE } //_____________________________________________________________________________ RooRealSumFunc::RooRealSumFunc(const char *name, const char *title) : RooAbsReal(name, title), _normIntMgr(this, 10), _haveLastCoef(false), - _funcList("!funcList", "List of functions", this), _coefList("!coefList", "List of coefficients", this), - _doFloor(false) + _funcList("!funcList", "List of functions", this), _coefList("!coefList", "List of coefficients", this) { // Constructor with name and title TRACE_CREATE @@ -80,8 +72,7 @@ RooRealSumFunc::RooRealSumFunc(const char *name, const char *title) RooRealSumFunc::RooRealSumFunc(const char *name, const char *title, RooAbsReal &func1, RooAbsReal &func2, RooAbsReal &coef1) : RooAbsReal(name, title), _normIntMgr(this, 10), _haveLastCoef(false), - _funcList("!funcList", "List of functions", this), _coefList("!coefList", "List of coefficients", this), - _doFloor(false) + _funcList("!funcList", "List of functions", this), _coefList("!coefList", "List of coefficients", this) { // Construct p.d.f consisting of coef1*func1 + (1-coef1)*func2 // The input coefficients and functions are allowed to be negative @@ -99,8 +90,7 @@ RooRealSumFunc::RooRealSumFunc(const char *name, const char *title, RooAbsReal & RooRealSumFunc::RooRealSumFunc(const char *name, const char *title, const RooArgList &inFuncList, const RooArgList &inCoefList) : RooAbsReal(name, title), _normIntMgr(this, 10), _haveLastCoef(false), - _funcList("!funcList", "List of functions", this), _coefList("!coefList", "List of coefficients", this), - _doFloor(false) + _funcList("!funcList", "List of functions", this), _coefList("!coefList", "List of coefficients", this) { // Constructor p.d.f implementing sum_i [ coef_i * func_i ], if N_coef==N_func // or sum_i [ coef_i * func_i ] + (1 - sum_i [ coef_i ] )* func_N if Ncoef==N_func-1 @@ -191,195 +181,19 @@ bool RooRealSumFunc::checkObservables(const RooArgSet *nset) const Int_t RooRealSumFunc::getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet2, const char *rangeName) const { - // cout << - // "RooRealSumFunc::getAnalyticalIntegralWN:"<") - // << endl; - // Advertise that all integrals can be handled internally. - - // Handle trivial no-integration scenario - if (allVars.empty()) - return 0; - if (_forceNumInt) - return 0; - - // Select subset of allVars that are actual dependents - analVars.add(allVars); - RooArgSet *normSet = normSet2 ? getObservables(normSet2) : 0; - - // Check if this configuration was created before - Int_t sterileIdx(-1); - CacheElem *cache = (CacheElem *)_normIntMgr.getObj(normSet, &analVars, &sterileIdx, RooNameReg::ptr(rangeName)); - if (cache) { - // cout << - // "RooRealSumFunc("<") - // << " -> " << _normIntMgr.lastIndex()+1 << " (cached)" << endl; - return _normIntMgr.lastIndex() + 1; - } - - // Create new cache element - cache = new CacheElem; - - // Make list of function projection and normalization integrals - for (const auto elm : _funcList) { - const auto func = static_cast(elm); - RooAbsReal *funcInt = func->createIntegral(analVars, rangeName); - if(funcInt->InheritsFrom(RooRealIntegral::Class())) ((RooRealIntegral*)funcInt)->setAllowComponentSelection(true); - cache->_funcIntList.addOwned(*funcInt); - if (normSet && normSet->getSize() > 0) { - RooAbsReal *funcNorm = func->createIntegral(*normSet); - cache->_funcNormList.addOwned(*funcNorm); - } - } - - // Store cache element - Int_t code = _normIntMgr.setObj(normSet, &analVars, (RooAbsCacheElement *)cache, RooNameReg::ptr(rangeName)); - - if (normSet) { - delete normSet; - } - - // cout << - // "RooRealSumFunc("<") - // << " -> " << code+1 << endl; - return code + 1; + return RooRealSumPdf::getAnalyticalIntegralWN(*this, _normIntMgr, _funcList, _coefList, allVars, analVars, normSet2, rangeName); } //_____________________________________________________________________________ double RooRealSumFunc::analyticalIntegralWN(Int_t code, const RooArgSet *normSet2, const char *rangeName) const { - // cout << - // "RooRealSumFunc::analyticalIntegralWN:"<") - // << endl; - // Implement analytical integrations by deferring integration of component - // functions to integrators of components - - // Handle trivial passthrough scenario - if (code == 0) - return getVal(normSet2); - - // WVE needs adaptation for rangeName feature - CacheElem *cache = (CacheElem *)_normIntMgr.getObjByIndex(code - 1); - if (cache == 0) { // revive the (sterilized) cache - // cout << - // "RooRealSumFunc("<") - // << ": reviving cache "<< endl; - std::unique_ptr vars(getParameters(RooArgSet())); - RooArgSet iset = _normIntMgr.selectFromSet2(*vars, code - 1); - RooArgSet nset = _normIntMgr.selectFromSet1(*vars, code - 1); - RooArgSet dummy; - Int_t code2 = getAnalyticalIntegralWN(iset, dummy, &nset, rangeName); - assert(code == code2); // must have revived the right (sterilized) slot... - (void)code2; - cache = (CacheElem *)_normIntMgr.getObjByIndex(code - 1); - assert(cache != 0); - } - - RooFIter funcIntIter = cache->_funcIntList.fwdIterator(); - RooFIter coefIter = _coefList.fwdIterator(); - RooFIter funcIter = _funcList.fwdIterator(); - RooAbsReal *coef(0), *funcInt(0), *func(0); - double value(0); - - // N funcs, N-1 coefficients - double lastCoef(1); - while ((coef = (RooAbsReal *)coefIter.next())) { - funcInt = (RooAbsReal *)funcIntIter.next(); - func = (RooAbsReal *)funcIter.next(); - double coefVal = coef->getVal(normSet2); - if (coefVal) { - assert(func); - if (normSet2 == 0 || func->isSelectedComp()) { - assert(funcInt); - value += funcInt->getVal() * coefVal; - } - lastCoef -= coef->getVal(normSet2); - } - } - - if (!_haveLastCoef) { - // Add last func with correct coefficient - funcInt = (RooAbsReal *)funcIntIter.next(); - if (normSet2 == 0 || func->isSelectedComp()) { - assert(funcInt); - value += funcInt->getVal() * lastCoef; - } - - // Warn about coefficient degeneration - if (lastCoef < 0 || lastCoef > 1) { - coutW(Eval) << "RooRealSumFunc::evaluate(" << GetName() - << " WARNING: sum of FUNC coefficients not in range [0-1], value=" << 1 - lastCoef << endl; - } - } - - double normVal(1); - if (normSet2 && normSet2->getSize() > 0) { - normVal = 0; - - // N funcs, N-1 coefficients - RooAbsReal *funcNorm; - RooFIter funcNormIter = cache->_funcNormList.fwdIterator(); - RooFIter coefIter2 = _coefList.fwdIterator(); - while ((coef = (RooAbsReal *)coefIter2.next())) { - funcNorm = (RooAbsReal *)funcNormIter.next(); - double coefVal = coef->getVal(normSet2); - if (coefVal) { - assert(funcNorm); - normVal += funcNorm->getVal() * coefVal; - } - } - - // Add last func with correct coefficient - if (!_haveLastCoef) { - funcNorm = (RooAbsReal *)funcNormIter.next(); - assert(funcNorm); - normVal += funcNorm->getVal() * lastCoef; - } - } - - return value / normVal; + return RooRealSumPdf::analyticalIntegralWN(*this, _normIntMgr, _funcList, _coefList, code, normSet2, rangeName, _haveWarned); } //_____________________________________________________________________________ std::list *RooRealSumFunc::binBoundaries(RooAbsRealLValue &obs, double xlo, double xhi) const { - list *sumBinB = 0; - bool needClean(false); - - RooFIter iter = _funcList.fwdIterator(); - RooAbsReal *func; - // Loop over components pdf - while ((func = (RooAbsReal *)iter.next())) { - - list *funcBinB = func->binBoundaries(obs, xlo, xhi); - - // Process hint - if (funcBinB) { - if (!sumBinB) { - // If this is the first hint, then just save it - sumBinB = funcBinB; - } else { - - list *newSumBinB = new list(sumBinB->size() + funcBinB->size()); - - // Merge hints into temporary array - merge(funcBinB->begin(), funcBinB->end(), sumBinB->begin(), sumBinB->end(), newSumBinB->begin()); - - // Copy merged array without duplicates to new sumBinBArrau - delete sumBinB; - delete funcBinB; - sumBinB = newSumBinB; - needClean = true; - } - } - } - - // Remove consecutive duplicates - if (needClean) { - list::iterator new_end = unique(sumBinB->begin(), sumBinB->end()); - sumBinB->erase(new_end, sumBinB->end()); - } - - return sumBinB; + return RooRealSumPdf::binBoundaries(_funcList, obs, xlo, xhi); } //_____________________________________________________________________________B @@ -401,45 +215,7 @@ bool RooRealSumFunc::isBinnedDistribution(const RooArgSet &obs) const //_____________________________________________________________________________ std::list *RooRealSumFunc::plotSamplingHint(RooAbsRealLValue &obs, double xlo, double xhi) const { - list *sumHint = 0; - bool needClean(false); - - RooFIter iter = _funcList.fwdIterator(); - RooAbsReal *func; - // Loop over components pdf - while ((func = (RooAbsReal *)iter.next())) { - - list *funcHint = func->plotSamplingHint(obs, xlo, xhi); - - // Process hint - if (funcHint) { - if (!sumHint) { - - // If this is the first hint, then just save it - sumHint = funcHint; - - } else { - - list *newSumHint = new list(sumHint->size() + funcHint->size()); - - // Merge hints into temporary array - merge(funcHint->begin(), funcHint->end(), sumHint->begin(), sumHint->end(), newSumHint->begin()); - - // Copy merged array without duplicates to new sumHintArrau - delete sumHint; - sumHint = newSumHint; - needClean = true; - } - } - } - - // Remove consecutive duplicates - if (needClean) { - list::iterator new_end = unique(sumHint->begin(), sumHint->end()); - sumHint->erase(new_end, sumHint->end()); - } - - return sumHint; + return RooRealSumPdf::plotSamplingHint(_funcList, obs, xlo, xhi); } //_____________________________________________________________________________ @@ -457,41 +233,10 @@ void RooRealSumFunc::setCacheAndTrackHints(RooArgSet &trackNodes) } } -//_____________________________________________________________________________ -void RooRealSumFunc::printMetaArgs(ostream &os) const -{ - // Customized printing of arguments of a RooRealSumFuncy to more intuitively reflect the contents of the - // product operator construction - - bool first(true); - - if (_coefList.getSize()!=0) { - auto funcIter = _funcList.begin(); - - for (const auto coef : _coefList) { - if (!first) { - os << " + "; - } else { - first = false; - } - const auto func = *(funcIter++); - os << coef->GetName() << " * " << func->GetName(); - } - - if (funcIter != _funcList.end()) { - os << " + [%] * " << (*funcIter)->GetName() ; - } - } else { +/// Customized printing of arguments of a RooRealSumFunc to more intuitively +/// reflect the contents of the product operator construction. - for (const auto func : _funcList) { - if (!first) { - os << " + "; - } else { - first = false; - } - os << func->GetName(); - } - } - - os << " "; +void RooRealSumFunc::printMetaArgs(std::ostream &os) const +{ + RooRealSumPdf::printMetaArgs(_funcList, _coefList, os); } diff --git a/roofit/roofitcore/src/RooRealSumPdf.cxx b/roofit/roofitcore/src/RooRealSumPdf.cxx index 18f4653fb64ac..7c6e0cc4b1109 100644 --- a/roofit/roofitcore/src/RooRealSumPdf.cxx +++ b/roofit/roofitcore/src/RooRealSumPdf.cxx @@ -357,29 +357,38 @@ bool RooRealSumPdf::checkObservables(const RooArgSet* nset) const Int_t RooRealSumPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars, const RooArgSet* normSet2, const char* rangeName) const +{ + return getAnalyticalIntegralWN(*this, _normIntMgr, _funcList, _coefList, allVars, analVars, normSet2, rangeName); +} + + +Int_t RooRealSumPdf::getAnalyticalIntegralWN(RooAbsReal const& caller, RooObjCacheManager & normIntMgr, + RooArgList const& funcList, RooArgList const& /*coefList*/, + RooArgSet& allVars, RooArgSet& analVars, + const RooArgSet* normSet2, const char* rangeName) { // Handle trivial no-integration scenario if (allVars.empty()) return 0 ; - if (_forceNumInt) return 0 ; + if (caller.getForceNumInt()) return 0 ; // Select subset of allVars that are actual dependents analVars.add(allVars) ; - RooArgSet* normSet = normSet2 ? getObservables(normSet2) : 0 ; + RooArgSet* normSet = normSet2 ? caller.getObservables(normSet2) : 0 ; // Check if this configuration was created before Int_t sterileIdx(-1) ; - CacheElem* cache = (CacheElem*) _normIntMgr.getObj(normSet,&analVars,&sterileIdx,RooNameReg::ptr(rangeName)) ; + auto* cache = static_cast(normIntMgr.getObj(normSet,&analVars,&sterileIdx,RooNameReg::ptr(rangeName))); if (cache) { //cout << "RooRealSumPdf("<") << " -> " << _normIntMgr.lastIndex()+1 << " (cached)" << endl; - return _normIntMgr.lastIndex()+1 ; + return normIntMgr.lastIndex()+1 ; } // Create new cache element cache = new CacheElem ; // Make list of function projection and normalization integrals - for (const auto elm : _funcList) { + for (const auto elm : funcList) { const auto func = static_cast(elm); RooAbsReal* funcInt = func->createIntegral(analVars,rangeName) ; @@ -392,7 +401,7 @@ Int_t RooRealSumPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& anal } // Store cache element - Int_t code = _normIntMgr.setObj(normSet,&analVars,(RooAbsCacheElement*)cache,RooNameReg::ptr(rangeName)) ; + Int_t code = normIntMgr.setObj(normSet,&analVars,(RooAbsCacheElement*)cache,RooNameReg::ptr(rangeName)) ; if (normSet) { delete normSet ; @@ -410,22 +419,31 @@ Int_t RooRealSumPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& anal /// functions to integrators of components. double RooRealSumPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet2, const char* rangeName) const +{ + return analyticalIntegralWN(*this, _normIntMgr, _funcList, _coefList, code, normSet2, rangeName, _haveWarned); +} + +double RooRealSumPdf::analyticalIntegralWN(RooAbsReal const& caller, RooObjCacheManager & normIntMgr, + RooArgList const& funcList, RooArgList const& coefList, + Int_t code, const RooArgSet* normSet2, const char* rangeName, + bool hasWarnedBefore) { // Handle trivial passthrough scenario - if (code==0) return getVal(normSet2) ; + if (code==0) return caller.getVal(normSet2) ; // WVE needs adaptation for rangeName feature - CacheElem* cache = (CacheElem*) _normIntMgr.getObjByIndex(code-1) ; + auto* cache = static_cast(normIntMgr.getObjByIndex(code-1)); if (cache==0) { // revive the (sterilized) cache //cout << "RooRealSumPdf("<") << ": reviving cache "<< endl; - std::unique_ptr vars( getParameters(RooArgSet()) ); - RooArgSet iset = _normIntMgr.selectFromSet2(*vars, code-1); - RooArgSet nset = _normIntMgr.selectFromSet1(*vars, code-1); + RooArgSet vars; + caller.getParameters(nullptr, vars); + RooArgSet iset = normIntMgr.selectFromSet2(vars, code-1); + RooArgSet nset = normIntMgr.selectFromSet1(vars, code-1); RooArgSet dummy; - Int_t code2 = getAnalyticalIntegralWN(iset,dummy,&nset,rangeName); + Int_t code2 = caller.getAnalyticalIntegralWN(iset,dummy,&nset,rangeName); R__ASSERT(code==code2); // must have revived the right (sterilized) slot... - cache = (CacheElem*) _normIntMgr.getObjByIndex(code-1) ; + cache = (CacheElem*) normIntMgr.getObjByIndex(code-1) ; R__ASSERT(cache!=0); } @@ -433,10 +451,10 @@ double RooRealSumPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet2 // N funcs, N-1 coefficients double lastCoef(1) ; - auto funcIt = _funcList.begin(); + auto funcIt = funcList.begin(); auto funcIntIt = cache->_funcIntList.begin(); - for (const auto coefArg : _coefList) { - assert(funcIt != _funcList.end()); + for (const auto coefArg : coefList) { + assert(funcIt != funcList.end()); const auto coef = static_cast(coefArg); const auto func = static_cast(*funcIt++); const auto funcInt = static_cast(*funcIntIt++); @@ -452,7 +470,9 @@ double RooRealSumPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet2 } } - if (!haveLastCoef()) { + const bool haveLastCoef = funcList.size() == coefList.size(); + + if (!haveLastCoef) { // Add last func with correct coefficient const auto func = static_cast(*funcIt); const auto funcInt = static_cast(*funcIntIt); @@ -464,8 +484,8 @@ double RooRealSumPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet2 } // Warn about coefficient degeneration - if (!_haveWarned && (lastCoef<0 || lastCoef>1)) { - coutW(Eval) << "RooRealSumPdf::evaluate(" << GetName() + if (!hasWarnedBefore && (lastCoef<0 || lastCoef>1)) { + oocoutW(&caller, Eval) << caller.ClassName() << "::evaluate(" << caller.GetName() << " WARNING: sum of FUNC coefficients not in range [0-1], value=" << 1-lastCoef << endl ; } @@ -477,7 +497,7 @@ double RooRealSumPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet2 // N funcs, N-1 coefficients auto funcNormIter = cache->_funcNormList.begin(); - for (const auto coefAsArg : _coefList) { + for (const auto coefAsArg : coefList) { auto coef = static_cast(coefAsArg); auto funcNorm = static_cast(*funcNormIter++); @@ -489,7 +509,7 @@ double RooRealSumPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet2 } // Add last func with correct coefficient - if (!haveLastCoef()) { + if (!haveLastCoef) { auto funcNorm = static_cast(*funcNormIter); assert(funcNorm); @@ -517,12 +537,17 @@ double RooRealSumPdf::expectedEvents(const RooArgSet* nset) const std::list* RooRealSumPdf::binBoundaries(RooAbsRealLValue& obs, double xlo, double xhi) const { - list* sumBinB = 0 ; + return binBoundaries(_funcList, obs, xlo, xhi); +} + + +std::list* RooRealSumPdf::binBoundaries(RooArgList const& funcList, RooAbsRealLValue& obs, double xlo, double xhi) +{ + std::list* sumBinB = nullptr; bool needClean(false) ; // Loop over components pdf - for (const auto elm : _funcList) { - auto func = static_cast(elm); + for (auto * func : static_range_cast(funcList)) { list* funcBinB = func->binBoundaries(obs,xlo,xhi) ; @@ -533,7 +558,7 @@ std::list* RooRealSumPdf::binBoundaries(RooAbsRealLValue& obs, double xl sumBinB = funcBinB ; } else { - list* newSumBinB = new list(sumBinB->size()+funcBinB->size()) ; + std::list* newSumBinB = new list(sumBinB->size()+funcBinB->size()) ; // Merge hints into temporary array merge(funcBinB->begin(),funcBinB->end(),sumBinB->begin(),sumBinB->end(),newSumBinB->begin()) ; @@ -580,11 +605,16 @@ bool RooRealSumPdf::isBinnedDistribution(const RooArgSet& obs) const std::list* RooRealSumPdf::plotSamplingHint(RooAbsRealLValue& obs, double xlo, double xhi) const { - list* sumHint = 0 ; + return plotSamplingHint(_funcList, obs, xlo, xhi); +} + +std::list* RooRealSumPdf::plotSamplingHint(RooArgList const& funcList, RooAbsRealLValue& obs, double xlo, double xhi) +{ + std::list* sumHint = 0 ; bool needClean(false) ; // Loop over components pdf - for (const auto elm : _funcList) { + for (const auto elm : funcList) { auto func = static_cast(elm); list* funcHint = func->plotSamplingHint(obs,xlo,xhi) ; @@ -613,8 +643,7 @@ std::list* RooRealSumPdf::plotSamplingHint(RooAbsRealLValue& obs, double // Remove consecutive duplicates if (needClean) { - list::iterator new_end = unique(sumHint->begin(),sumHint->end()) ; - sumHint->erase(new_end,sumHint->end()) ; + sumHint->erase(std::unique(sumHint->begin(),sumHint->end()), sumHint->end()) ; } return sumHint ; @@ -637,20 +666,25 @@ void RooRealSumPdf::setCacheAndTrackHints(RooArgSet& trackNodes) } - //////////////////////////////////////////////////////////////////////////////// /// Customized printing of arguments of a RooRealSumPdf to more intuitively reflect the contents of the /// product operator construction void RooRealSumPdf::printMetaArgs(ostream& os) const +{ + printMetaArgs(_funcList, _coefList, os); +} + + +void RooRealSumPdf::printMetaArgs(RooArgList const& funcList, RooArgList const& coefList, ostream& os) { bool first(true) ; - if (_coefList.getSize()!=0) { - auto funcIter = _funcList.begin(); + if (!coefList.empty()) { + auto funcIter = funcList.begin(); - for (const auto coef : _coefList) { + for (const auto coef : coefList) { if (!first) { os << " + " ; } else { @@ -660,12 +694,12 @@ void RooRealSumPdf::printMetaArgs(ostream& os) const os << coef->GetName() << " * " << func->GetName(); } - if (funcIter != _funcList.end()) { + if (funcIter != funcList.end()) { os << " + [%] * " << (*funcIter)->GetName() ; } } else { - for (const auto func : _funcList) { + for (const auto func : funcList) { if (!first) { os << " + " ; } else { From f5bff32644e50f3754580351445a38cba62d120a Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Tue, 28 Jun 2022 00:30:40 +0200 Subject: [PATCH 047/104] [RF][squash-on-merge] Avoid code duplication in RooRealSumPdf/Func --- roofit/roofitcore/inc/RooRealSumFunc.h | 8 +-- roofit/roofitcore/inc/RooRealSumPdf.h | 7 ++ roofit/roofitcore/src/RooRealSumFunc.cxx | 87 ++---------------------- roofit/roofitcore/src/RooRealSumPdf.cxx | 50 ++++++++++---- 4 files changed, 51 insertions(+), 101 deletions(-) diff --git a/roofit/roofitcore/inc/RooRealSumFunc.h b/roofit/roofitcore/inc/RooRealSumFunc.h index 7190a39667deb..20d3663855414 100644 --- a/roofit/roofitcore/inc/RooRealSumFunc.h +++ b/roofit/roofitcore/inc/RooRealSumFunc.h @@ -16,7 +16,6 @@ #ifndef ROO_REAL_SUM_FUNC #define ROO_REAL_SUM_FUNC -#include "RooRealSumPdf.h" #include "RooAbsPdf.h" #include "RooListProxy.h" #include "RooAICRegistry.h" @@ -30,7 +29,7 @@ class RooRealSumFunc : public RooAbsReal { RooRealSumFunc(const char *name, const char *title); RooRealSumFunc(const char *name, const char *title, const RooArgList &funcList, const RooArgList &coefList); RooRealSumFunc(const char *name, const char *title, RooAbsReal &func1, RooAbsReal &func2, RooAbsReal &coef1); - RooRealSumFunc(const RooRealSumFunc &other, const char *name = 0); + RooRealSumFunc(const RooRealSumFunc &other, const char *name = nullptr); TObject *clone(const char *newname) const override { return new RooRealSumFunc(*this, newname); } ~RooRealSumFunc() override; @@ -39,8 +38,8 @@ class RooRealSumFunc : public RooAbsReal { bool forceAnalyticalInt(const RooAbsArg &arg) const override { return arg.isFundamental(); } Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &numVars, const RooArgSet *normSet, - const char *rangeName = 0) const override; - double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName = 0) const override; + const char *rangeName = nullptr) const override; + double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName = nullptr) const override; const RooArgList &funcList() const { return _funcList; } const RooArgList &coefList() const { return _coefList; } @@ -64,7 +63,6 @@ class RooRealSumFunc : public RooAbsReal { } protected: - using CacheElem = RooRealSumPdf::CacheElem; mutable RooObjCacheManager _normIntMgr; //! The integration cache manager bool _haveLastCoef; diff --git a/roofit/roofitcore/inc/RooRealSumPdf.h b/roofit/roofitcore/inc/RooRealSumPdf.h index 051a87f7c39d8..cdb887b36a1de 100644 --- a/roofit/roofitcore/inc/RooRealSumPdf.h +++ b/roofit/roofitcore/inc/RooRealSumPdf.h @@ -97,6 +97,10 @@ class RooRealSumPdf : public RooAbsPdf { friend class RooRealSumFunc; + static void initializeFuncsAndCoefs(RooAbsReal const& caller, + const RooArgList& inFuncList, const RooArgList& inCoefList, + RooArgList& funcList, RooArgList& coefList); + static double evaluate(RooAbsReal const& caller, RooArgList const& funcList, RooArgList const& coefList, @@ -118,9 +122,12 @@ class RooRealSumPdf : public RooAbsPdf { RooArgList const& funcList, RooAbsRealLValue& /*obs*/, double /*xlo*/, double /*xhi*/); static std::list* plotSamplingHint( RooArgList const& funcList, RooAbsRealLValue& /*obs*/, double /*xlo*/, double /*xhi*/); + static bool isBinnedDistribution(RooArgList const& funcList, const RooArgSet& obs); static void printMetaArgs(RooArgList const& funcList, RooArgList const& coefList, std::ostream& os); + static void setCacheAndTrackHints(RooArgList const& funcList, RooArgSet& trackNodes); + ClassDefOverride(RooRealSumPdf, 5) // PDF constructed from a sum of (non-pdf) functions }; diff --git a/roofit/roofitcore/src/RooRealSumFunc.cxx b/roofit/roofitcore/src/RooRealSumFunc.cxx index 4f271a8a28780..5205f3f8c2cb8 100644 --- a/roofit/roofitcore/src/RooRealSumFunc.cxx +++ b/roofit/roofitcore/src/RooRealSumFunc.cxx @@ -34,19 +34,9 @@ /// - RooRealSumFunc is a sum of functions. It is neither normalised, nor need it be positive. #include "RooRealSumFunc.h" - -#include "RooRealVar.h" -#include "RooAddGenContext.h" -#include "RooRealConstant.h" -#include "RooRealIntegral.h" -#include "RooMsgService.h" -#include "RooNameReg.h" +#include "RooRealSumPdf.h" #include "RooTrace.h" -#include "Riostream.h" - -#include - ClassImp(RooRealSumFunc); bool RooRealSumFunc::_doFloorGlobal = false; @@ -71,8 +61,7 @@ RooRealSumFunc::RooRealSumFunc(const char *name, const char *title) //_____________________________________________________________________________ RooRealSumFunc::RooRealSumFunc(const char *name, const char *title, RooAbsReal &func1, RooAbsReal &func2, RooAbsReal &coef1) - : RooAbsReal(name, title), _normIntMgr(this, 10), _haveLastCoef(false), - _funcList("!funcList", "List of functions", this), _coefList("!coefList", "List of coefficients", this) + : RooRealSumFunc{name, title} { // Construct p.d.f consisting of coef1*func1 + (1-coef1)*func2 // The input coefficients and functions are allowed to be negative @@ -89,8 +78,7 @@ RooRealSumFunc::RooRealSumFunc(const char *name, const char *title, RooAbsReal & //_____________________________________________________________________________ RooRealSumFunc::RooRealSumFunc(const char *name, const char *title, const RooArgList &inFuncList, const RooArgList &inCoefList) - : RooAbsReal(name, title), _normIntMgr(this, 10), _haveLastCoef(false), - _funcList("!funcList", "List of functions", this), _coefList("!coefList", "List of coefficients", this) + : RooRealSumFunc{name, title} { // Constructor p.d.f implementing sum_i [ coef_i * func_i ], if N_coef==N_func // or sum_i [ coef_i * func_i ] + (1 - sum_i [ coef_i ] )* func_N if Ncoef==N_func-1 @@ -98,51 +86,7 @@ RooRealSumFunc::RooRealSumFunc(const char *name, const char *title, const RooArg // All coefficients and functions are allowed to be negative // but the sum is not, which is enforced at runtime. - const std::string ownName(GetName() ? GetName() : ""); - if (!(inFuncList.getSize() == inCoefList.getSize() + 1 || inFuncList.getSize() == inCoefList.getSize())) { - coutE(InputArguments) << "RooRealSumFunc::RooRealSumFunc(" << ownName - << ") number of pdfs and coefficients inconsistent, must have Nfunc=Ncoef or Nfunc=Ncoef+1" - << "\n"; - assert(0); - } - - // Constructor with N functions and N or N-1 coefs - - std::string funcName; - for (unsigned int i = 0; i < inCoefList.size(); ++i) { - const auto& func = inFuncList[i]; - const auto& coef = inCoefList[i]; - - if (!dynamic_cast(&coef)) { - const std::string coefName(coef.GetName() ? coef.GetName() : ""); - coutW(InputArguments) << "RooRealSumFunc::RooRealSumFunc(" << ownName << ") coefficient " << coefName - << " is not of type RooAbsReal, ignored" - << "\n"; - continue; - } - if (!dynamic_cast(&func)) { - funcName = (func.GetName() ? func.GetName() : ""); - coutW(InputArguments) << "RooRealSumFunc::RooRealSumFunc(" << ownName << ") func " << funcName - << " is not of type RooAbsReal, ignored" - << "\n"; - continue; - } - _funcList.add(func); - _coefList.add(coef); - } - - if (inFuncList.size() == inCoefList.size() + 1) { - const auto& func = inFuncList[inFuncList.size()-1]; - if (!dynamic_cast(&func)) { - funcName = (func.GetName() ? func.GetName() : ""); - coutE(InputArguments) << "RooRealSumFunc::RooRealSumFunc(" << ownName << ") last func " << funcName - << " is not of type RooAbsReal, fatal error\n"; - throw std::invalid_argument("RooRealSumFunc: Function passed as is not of type RooAbsReal."); - } - _funcList.add(func); - } else { - _haveLastCoef = true; - } + RooRealSumPdf::initializeFuncsAndCoefs(*this, inFuncList, inCoefList, _funcList, _coefList); TRACE_CREATE } @@ -199,17 +143,7 @@ std::list *RooRealSumFunc::binBoundaries(RooAbsRealLValue &obs, double x //_____________________________________________________________________________B bool RooRealSumFunc::isBinnedDistribution(const RooArgSet &obs) const { - // If all components that depend on obs are binned that so is the product - - RooFIter iter = _funcList.fwdIterator(); - RooAbsReal *func; - while ((func = (RooAbsReal *)iter.next())) { - if (func->dependsOn(obs) && !func->isBinnedDistribution(obs)) { - return false; - } - } - - return true; + return RooRealSumPdf::isBinnedDistribution(_funcList, obs); } //_____________________________________________________________________________ @@ -221,16 +155,7 @@ std::list *RooRealSumFunc::plotSamplingHint(RooAbsRealLValue &obs, doubl //_____________________________________________________________________________ void RooRealSumFunc::setCacheAndTrackHints(RooArgSet &trackNodes) { - // Label OK'ed components of a RooRealSumFunc with cache-and-track - RooFIter siter = funcList().fwdIterator(); - RooAbsArg *sarg; - while ((sarg = siter.next())) { - if (sarg->canNodeBeCached() == Always) { - trackNodes.add(*sarg); - // cout << "tracking node RealSumFunc component " << sarg->ClassName() << "::" << sarg->GetName() << endl - // ; - } - } + RooRealSumPdf::setCacheAndTrackHints(_funcList, trackNodes); } /// Customized printing of arguments of a RooRealSumFunc to more intuitively diff --git a/roofit/roofitcore/src/RooRealSumPdf.cxx b/roofit/roofitcore/src/RooRealSumPdf.cxx index 7c6e0cc4b1109..ae7ce6d91c6a7 100644 --- a/roofit/roofitcore/src/RooRealSumPdf.cxx +++ b/roofit/roofitcore/src/RooRealSumPdf.cxx @@ -140,11 +140,21 @@ RooRealSumPdf::RooRealSumPdf(const char *name, const char *title, RooRealSumPdf(name, title) { _extended = extended; + RooRealSumPdf::initializeFuncsAndCoefs(*this, inFuncList, inCoefList, _funcList, _coefList); +} + + +void RooRealSumPdf::initializeFuncsAndCoefs(RooAbsReal const& caller, + const RooArgList& inFuncList, const RooArgList& inCoefList, + RooArgList& funcList, RooArgList& coefList) +{ + const std::string className = caller.ClassName(); + const std::string constructorName = className + "::" + className; - if (!(inFuncList.getSize()==inCoefList.getSize()+1 || inFuncList.getSize()==inCoefList.getSize())) { - coutE(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() - << ") number of pdfs and coefficients inconsistent, must have Nfunc=Ncoef or Nfunc=Ncoef+1" << endl ; - throw std::invalid_argument("RooRealSumPdf: Number of PDFs and coefficients is inconsistent."); + if (!(inFuncList.size()==inCoefList.size()+1 || inFuncList.size()==inCoefList.size())) { + oocoutE(&caller, InputArguments) << constructorName << "(" << caller.GetName() + << ") number of pdfs and coefficients inconsistent, must have Nfunc=Ncoef or Nfunc=Ncoef+1" << std::endl; + throw std::invalid_argument(className + ": Number of PDFs and coefficients is inconsistent."); } // Constructor with N functions and N or N-1 coefs @@ -153,24 +163,24 @@ RooRealSumPdf::RooRealSumPdf(const char *name, const char *title, const auto& coef = inCoefList[i]; if (!dynamic_cast(&coef)) { - coutW(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() << ") coefficient " << coef.GetName() << " is not of type RooAbsReal, ignored" << endl ; + oocoutW(&caller, InputArguments) << constructorName << "(" << caller.GetName() << ") coefficient " << coef.GetName() << " is not of type RooAbsReal, ignored" << std::endl ; continue ; } if (!dynamic_cast(&func)) { - coutW(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() << ") func " << func.GetName() << " is not of type RooAbsReal, ignored" << endl ; + oocoutW(&caller, InputArguments) << constructorName << "(" << caller.GetName() << ") func " << func.GetName() << " is not of type RooAbsReal, ignored" << std::endl ; continue ; } - _funcList.add(func) ; - _coefList.add(coef) ; + funcList.add(func) ; + coefList.add(coef) ; } if (inFuncList.size() == inCoefList.size() + 1) { const auto& func = inFuncList[inFuncList.size()-1]; if (!dynamic_cast(&func)) { - coutE(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() << ") last func " << func.GetName() << " is not of type RooAbsReal, fatal error" << endl ; - throw std::invalid_argument("RooRealSumPdf: Function passed as is not of type RooAbsReal."); + oocoutE(&caller, InputArguments) << constructorName << "(" << caller.GetName() << ") last func " << func.GetName() << " is not of type RooAbsReal, fatal error" << std::endl ; + throw std::invalid_argument(className + ": Function passed as is not of type RooAbsReal."); } - _funcList.add(func); + funcList.add(func); } } @@ -586,7 +596,13 @@ std::list* RooRealSumPdf::binBoundaries(RooArgList const& funcList, RooA /// Check if all components that depend on `obs` are binned. bool RooRealSumPdf::isBinnedDistribution(const RooArgSet& obs) const { - for (const auto elm : _funcList) { + return isBinnedDistribution(_funcList, obs); +} + + +bool RooRealSumPdf::isBinnedDistribution(RooArgList const& funcList, const RooArgSet& obs) +{ + for (const auto elm : funcList) { auto func = static_cast(elm); if (func->dependsOn(obs) && !func->isBinnedDistribution(obs)) { @@ -599,8 +615,6 @@ bool RooRealSumPdf::isBinnedDistribution(const RooArgSet& obs) const - - //////////////////////////////////////////////////////////////////////////////// std::list* RooRealSumPdf::plotSamplingHint(RooAbsRealLValue& obs, double xlo, double xhi) const @@ -657,7 +671,13 @@ std::list* RooRealSumPdf::plotSamplingHint(RooArgList const& funcList, R void RooRealSumPdf::setCacheAndTrackHints(RooArgSet& trackNodes) { - for (const auto sarg : _funcList) { + setCacheAndTrackHints(_funcList, trackNodes); +} + + +void RooRealSumPdf::setCacheAndTrackHints(RooArgList const& funcList, RooArgSet& trackNodes) +{ + for (const auto sarg : funcList) { if (sarg->canNodeBeCached()==Always) { trackNodes.add(*sarg) ; //cout << "tracking node RealSumPdf component " << sarg->ClassName() << "::" << sarg->GetName() << endl ; From f61a4e8ed9c629ade3a6ba1bece5e31c53b8d9d4 Mon Sep 17 00:00:00 2001 From: Bertrand Bellenot Date: Tue, 28 Jun 2022 11:06:10 +0200 Subject: [PATCH 048/104] Fix compilation error of ntuple_types on Windows Fix the following compilation error of `ntuple_types` on Windows: ``` ntuple_types.obj : error LNK2019: unresolved external symbol "const ROOT::Experimental::RRecordField::`vftable'" (??_7RRecordField@Experimental@ROOT@@6B@) referenced in function "private: virtual void __thiscall RNTuple_CreateField_Test::TestBody(void)" (?TestBody@RNTuple_CreateField_Test@@EAEXXZ) [C:\Users\bellenot\build\release\tree\ntuple\v7\test\ntuple_types.vcxproj] C:\Users\bellenot\build\release\tree\ntuple\v7\test\Release\ntuple_types.exe : fatal error LNK1120: 1 unresolved externals [C:\Users\bellenot\build\release\tree\ntuple\v7\test\ntuple_types.vcxproj] ``` --- tree/ntuple/v7/inc/ROOT/RField.hxx | 5 +---- tree/ntuple/v7/src/RField.cxx | 6 ++++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tree/ntuple/v7/inc/ROOT/RField.hxx b/tree/ntuple/v7/inc/ROOT/RField.hxx index d4a5a6f0cea92..e2e388e030ca2 100644 --- a/tree/ntuple/v7/inc/ROOT/RField.hxx +++ b/tree/ntuple/v7/inc/ROOT/RField.hxx @@ -365,10 +365,7 @@ public: /// Construct a RRecordField based on a vector of child fields. The ownership of the child fields is transferred /// to the RRecordField instance. RRecordField(std::string_view fieldName, std::vector> &&itemFields); - RRecordField(std::string_view fieldName, std::vector> &itemFields) - : RRecordField(fieldName, std::move(itemFields)) - { - } + RRecordField(std::string_view fieldName, std::vector> &itemFields); RRecordField(RRecordField&& other) = default; RRecordField& operator =(RRecordField&& other) = default; ~RRecordField() = default; diff --git a/tree/ntuple/v7/src/RField.cxx b/tree/ntuple/v7/src/RField.cxx index 904f53ee13c32..151a45769d98b 100644 --- a/tree/ntuple/v7/src/RField.cxx +++ b/tree/ntuple/v7/src/RField.cxx @@ -945,6 +945,12 @@ ROOT::Experimental::RRecordField::RRecordField(std::string_view fieldName, fSize += GetItemPadding(fSize, fMaxAlignment); } +ROOT::Experimental::RRecordField::RRecordField(std::string_view fieldName, + std::vector> &itemFields) + : ROOT::Experimental::RRecordField(fieldName, std::move(itemFields)) +{ +} + std::size_t ROOT::Experimental::RRecordField::GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const { if (itemAlignment > 1) { From 1c5d570ffb3034aab76c5a176db077bfbb7e6e54 Mon Sep 17 00:00:00 2001 From: Tapasweni Pathak Date: Sat, 25 Jun 2022 21:55:51 +0530 Subject: [PATCH 049/104] Revert "Survive #pragma once from virtual file." This reverts commit 71e133dd0391deac1cf3761d2c5c253b3cb247ff. --- interpreter/llvm/src/tools/clang/lib/Lex/Pragma.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/interpreter/llvm/src/tools/clang/lib/Lex/Pragma.cpp b/interpreter/llvm/src/tools/clang/lib/Lex/Pragma.cpp index 25231abf9606a..4e4db668551f8 100644 --- a/interpreter/llvm/src/tools/clang/lib/Lex/Pragma.cpp +++ b/interpreter/llvm/src/tools/clang/lib/Lex/Pragma.cpp @@ -386,11 +386,9 @@ void Preprocessor::HandlePragmaOnce(Token &OnceTok) { return; } - if (getCurrentFileLexer()->getFileEntry()) { - // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc. - // Mark the file as a once-only file now. - HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry()); - } + // Get the current file lexer we're looking at. Ignore _Pragma 'files' etc. + // Mark the file as a once-only file now. + HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry()); } void Preprocessor::HandlePragmaMark() { From fb25d1ab359f054db6cccef710f987131173c920 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Sun, 26 Jun 2022 09:26:21 +0000 Subject: [PATCH 050/104] Revert "Merge Ctors from nested transactions" This commit reverts root-project/root@69568116cd The CtorsConstants variable is not used. The commit log has a simple tests which now works without this patch. Thanks to Jonas Hahnfeld (@hahnjo) for pointing this out! --- .../src/tools/clang/lib/CodeGen/CodeGenModule.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/interpreter/llvm/src/tools/clang/lib/CodeGen/CodeGenModule.cpp b/interpreter/llvm/src/tools/clang/lib/CodeGen/CodeGenModule.cpp index c40061dcba2cf..9bf7036c85639 100644 --- a/interpreter/llvm/src/tools/clang/lib/CodeGen/CodeGenModule.cpp +++ b/interpreter/llvm/src/tools/clang/lib/CodeGen/CodeGenModule.cpp @@ -1159,25 +1159,10 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) { llvm::StructType *CtorStructTy = llvm::StructType::get( Int32Ty, CtorPFTy, VoidPtrTy); - // Construct the constructor and destructor arrays. ConstantInitBuilder builder(*this); auto ctors = builder.beginArray(CtorStructTy); - SmallVector CtorsConstants; - // Add existing ones: - if (llvm::GlobalVariable* OldGlobal - = TheModule.getGlobalVariable(GlobalName, true)) { - if (const llvm::ConstantArray* CArr = - llvm::dyn_cast(OldGlobal->getInitializer())) { - uint64_t OldSize = CArr->getType()->getNumElements(); - for (uint64_t Idx = 0; Idx < OldSize; ++Idx) { - CtorsConstants.push_back(CArr->getAggregateElement(Idx)); - } - } - OldGlobal->eraseFromParent(); - } - for (const auto &I : Fns) { auto ctor = ctors.beginStruct(CtorStructTy); ctor.addInt(Int32Ty, I.Priority); From 3e5a8736d09360c5aab595295b8c5a7840c45997 Mon Sep 17 00:00:00 2001 From: saisoma123 Date: Thu, 9 Jun 2022 16:56:46 -0400 Subject: [PATCH 051/104] Added new starting point for cpt.py. Added new main block because this was mentioned in the meta issue list (#406 in cling) as one of the rewrite steps. This also allows for the main code to be run as opposed to running the main code plus the function defintions. --- interpreter/cling/tools/packaging/cpt.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interpreter/cling/tools/packaging/cpt.py b/interpreter/cling/tools/packaging/cpt.py index 60e3c44098e78..f609452746925 100755 --- a/interpreter/cling/tools/packaging/cpt.py +++ b/interpreter/cling/tools/packaging/cpt.py @@ -1835,7 +1835,8 @@ def custom_input(prompt, always_yes=False): # Global variables # ############################################################################### -workdir = os.path.abspath(os.path.expanduser(args['with_workdir'])) +if __name__ == "__main__": + workdir = os.path.abspath(os.path.expanduser(args['with_workdir'])) srcdir = os.path.join(workdir, 'cling-src') CLING_SRC_DIR = os.path.join(srcdir, 'tools', 'cling') CPT_SRC_DIR = os.path.join(CLING_SRC_DIR, 'tools', 'packaging') From 49b9fd317622d2c6eea08f400dd6b173cf068bba Mon Sep 17 00:00:00 2001 From: saisoma123 Date: Fri, 10 Jun 2022 13:59:10 -0400 Subject: [PATCH 052/104] Edited verbose output flag --- interpreter/cling/tools/packaging/cpt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interpreter/cling/tools/packaging/cpt.py b/interpreter/cling/tools/packaging/cpt.py index f609452746925..7c7cb987875c5 100755 --- a/interpreter/cling/tools/packaging/cpt.py +++ b/interpreter/cling/tools/packaging/cpt.py @@ -518,8 +518,8 @@ def make(self, targets, flags=''): exec_subprocess_call('%s --build . --target %s %s' % (CMAKE, target, flags), LLVM_OBJ_ROOT) else: - if args['verbose']: flags += ' VERBOSE=1' - exec_subprocess_call('make -j%d %s %s' % (self.cores, targets, flags), + if args['verbose']: exec_subprocess_call('cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON', LLVM_OBJ_ROOT) + exec_subprocess_call('make -j %d %s %s' % (self.cores, targets, flags), LLVM_OBJ_ROOT) def compile(arg): From 0f2436d890381494712d1e168e11b23d85215f63 Mon Sep 17 00:00:00 2001 From: saisoma123 Date: Mon, 13 Jun 2022 17:55:34 -0400 Subject: [PATCH 053/104] Added verbose flag to the llvm_flags variable --- interpreter/cling/tools/packaging/cpt.py | 35 ++++++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/interpreter/cling/tools/packaging/cpt.py b/interpreter/cling/tools/packaging/cpt.py index 7c7cb987875c5..986c653c2f5ab 100755 --- a/interpreter/cling/tools/packaging/cpt.py +++ b/interpreter/cling/tools/packaging/cpt.py @@ -240,7 +240,13 @@ def download_llvm_binary(): llvm_dir = os.path.join("/usr", "lib", "llvm-"+llvm_vers) if llvm_config_path[-1:] == "\n": llvm_config_path = llvm_config_path[:-1] - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ + if args['verbose']: + llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ + -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON".format(llvm_dir, llvm_config_path, + os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), + os.path.join(llvm_dir, 'bin')) + else: + llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(llvm_dir, llvm_config_path, os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), os.path.join(llvm_dir, 'bin')) @@ -255,17 +261,29 @@ def download_llvm_binary(): llvm_config_path = os.path.join(llvm_dir, "bin", "llvm-config") if llvm_config_path[-1:] == "\n": llvm_config_path = llvm_config_path[:-1] - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ + if args['verbose']: + llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ + -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON".format(llvm_dir, llvm_config_path, + os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), + os.path.join(llvm_dir, 'bin')) + else: + llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(llvm_dir, llvm_config_path, - os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), - os.path.join(llvm_dir, 'bin')) + os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), + os.path.join(llvm_dir, 'bin')) else: raise Exception("Building clang using LLVM binary not possible. Please invoke cpt without --with-binary-llvm and --with-llvm-tar flags") if tar_required: - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ - -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(srcdir, os.path.join(srcdir, 'bin', 'llvm-config'), - os.path.join(srcdir, 'lib'), os.path.join(srcdir, 'include'), os.path.join(srcdir, 'bin', 'llvm-tblgen'), - os.path.join(srcdir, 'bin')) + if args['verbose']: + llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ + -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON".format(llvm_dir, llvm_config_path, + os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), + os.path.join(llvm_dir, 'bin')) + else: + llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ + -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(llvm_dir, llvm_config_path, + os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), + os.path.join(llvm_dir, 'bin')) if DIST=="Ubuntu" and REV=='16.04' and is_os_64bit(): download_link = 'http://releases.llvm.org/5.0.2/clang+llvm-5.0.2-x86_64-linux-gnu-ubuntu-16.04.tar.xz' exec_subprocess_call('wget %s' % download_link, workdir) @@ -518,7 +536,6 @@ def make(self, targets, flags=''): exec_subprocess_call('%s --build . --target %s %s' % (CMAKE, target, flags), LLVM_OBJ_ROOT) else: - if args['verbose']: exec_subprocess_call('cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON', LLVM_OBJ_ROOT) exec_subprocess_call('make -j %d %s %s' % (self.cores, targets, flags), LLVM_OBJ_ROOT) From 5daf77a63ffb3130927a5b1bc4920cfe77e2f5cb Mon Sep 17 00:00:00 2001 From: saisoma123 Date: Tue, 14 Jun 2022 11:19:22 -0400 Subject: [PATCH 054/104] Added verbose flag to the llvm_flags variable, if the verbose option is called --- interpreter/cling/tools/packaging/cpt.py | 33 ++++++++---------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/interpreter/cling/tools/packaging/cpt.py b/interpreter/cling/tools/packaging/cpt.py index 986c653c2f5ab..e6981da25e684 100755 --- a/interpreter/cling/tools/packaging/cpt.py +++ b/interpreter/cling/tools/packaging/cpt.py @@ -239,17 +239,13 @@ def download_llvm_binary(): if llvm_config_path != '' and tar_required is False: llvm_dir = os.path.join("/usr", "lib", "llvm-"+llvm_vers) if llvm_config_path[-1:] == "\n": - llvm_config_path = llvm_config_path[:-1] - if args['verbose']: - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ - -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON".format(llvm_dir, llvm_config_path, - os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), - os.path.join(llvm_dir, 'bin')) - else: - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ + llvm_config_path = llvm_config_path[:-1] + llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(llvm_dir, llvm_config_path, os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), os.path.join(llvm_dir, 'bin')) + if args['verbose']: + llvm_flags = "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" else: tar_required = True elif DIST == 'MacOSX': @@ -261,29 +257,22 @@ def download_llvm_binary(): llvm_config_path = os.path.join(llvm_dir, "bin", "llvm-config") if llvm_config_path[-1:] == "\n": llvm_config_path = llvm_config_path[:-1] - if args['verbose']: - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ - -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON".format(llvm_dir, llvm_config_path, - os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), - os.path.join(llvm_dir, 'bin')) - else: - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ + llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(llvm_dir, llvm_config_path, os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), os.path.join(llvm_dir, 'bin')) + if args['verbose']: + llvm_flags += "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" else: raise Exception("Building clang using LLVM binary not possible. Please invoke cpt without --with-binary-llvm and --with-llvm-tar flags") if tar_required: - if args['verbose']: - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ - -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON".format(llvm_dir, llvm_config_path, - os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), - os.path.join(llvm_dir, 'bin')) - else: - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ + + llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(llvm_dir, llvm_config_path, os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), os.path.join(llvm_dir, 'bin')) + if args['verbose']: + llvm_flags += "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" if DIST=="Ubuntu" and REV=='16.04' and is_os_64bit(): download_link = 'http://releases.llvm.org/5.0.2/clang+llvm-5.0.2-x86_64-linux-gnu-ubuntu-16.04.tar.xz' exec_subprocess_call('wget %s' % download_link, workdir) From fb4d8455aece141948e7444a1d80ad1d1207cd04 Mon Sep 17 00:00:00 2001 From: saisoma123 Date: Tue, 14 Jun 2022 11:22:34 -0400 Subject: [PATCH 055/104] Forgot extra plus sign --- interpreter/cling/tools/packaging/cpt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/cling/tools/packaging/cpt.py b/interpreter/cling/tools/packaging/cpt.py index e6981da25e684..db90599fd5365 100755 --- a/interpreter/cling/tools/packaging/cpt.py +++ b/interpreter/cling/tools/packaging/cpt.py @@ -245,7 +245,7 @@ def download_llvm_binary(): os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), os.path.join(llvm_dir, 'bin')) if args['verbose']: - llvm_flags = "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" + llvm_flags += "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" else: tar_required = True elif DIST == 'MacOSX': From c84bd4dfc41b675bdb7f4fbdda98284737bca5c2 Mon Sep 17 00:00:00 2001 From: saisoma123 Date: Tue, 14 Jun 2022 11:23:36 -0400 Subject: [PATCH 056/104] Formatting changes --- interpreter/cling/tools/packaging/cpt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/cling/tools/packaging/cpt.py b/interpreter/cling/tools/packaging/cpt.py index db90599fd5365..60eb6b4ee1d4e 100755 --- a/interpreter/cling/tools/packaging/cpt.py +++ b/interpreter/cling/tools/packaging/cpt.py @@ -272,7 +272,7 @@ def download_llvm_binary(): os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), os.path.join(llvm_dir, 'bin')) if args['verbose']: - llvm_flags += "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" + llvm_flags += "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" if DIST=="Ubuntu" and REV=='16.04' and is_os_64bit(): download_link = 'http://releases.llvm.org/5.0.2/clang+llvm-5.0.2-x86_64-linux-gnu-ubuntu-16.04.tar.xz' exec_subprocess_call('wget %s' % download_link, workdir) From 938815ac1db84afeb9825bca72ed8eed04ab3b35 Mon Sep 17 00:00:00 2001 From: saisoma123 Date: Tue, 28 Jun 2022 00:24:14 -0400 Subject: [PATCH 057/104] Fixed formatting and made new helper function for setting llvm_flags --- interpreter/cling/tools/packaging/cpt.py | 33 ++++++++++-------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/interpreter/cling/tools/packaging/cpt.py b/interpreter/cling/tools/packaging/cpt.py index 60eb6b4ee1d4e..33452ac6357b9 100755 --- a/interpreter/cling/tools/packaging/cpt.py +++ b/interpreter/cling/tools/packaging/cpt.py @@ -227,6 +227,15 @@ def update_old_llvm(): else: get_fresh_llvm() +def llvm_flag_setter(llvm_dir, llvm_config_path): + flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ + -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(llvm_dir, llvm_config_path, + os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), + os.path.join(llvm_dir, 'bin')) + if args['verbose']: + flags += " -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" + return flags + def download_llvm_binary(): global llvm_flags, tar_required box_draw("Fetching LLVM binary") @@ -239,13 +248,8 @@ def download_llvm_binary(): if llvm_config_path != '' and tar_required is False: llvm_dir = os.path.join("/usr", "lib", "llvm-"+llvm_vers) if llvm_config_path[-1:] == "\n": - llvm_config_path = llvm_config_path[:-1] - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ - -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(llvm_dir, llvm_config_path, - os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), - os.path.join(llvm_dir, 'bin')) - if args['verbose']: - llvm_flags += "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" + llvm_config_path = llvm_config_path[:-1] + llvm_flags = llvm_flag_setter(llvm_dir, llvm_config_path) else: tar_required = True elif DIST == 'MacOSX': @@ -257,22 +261,11 @@ def download_llvm_binary(): llvm_config_path = os.path.join(llvm_dir, "bin", "llvm-config") if llvm_config_path[-1:] == "\n": llvm_config_path = llvm_config_path[:-1] - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ - -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(llvm_dir, llvm_config_path, - os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), - os.path.join(llvm_dir, 'bin')) - if args['verbose']: - llvm_flags += "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" + llvm_flags = llvm_flag_setter(llvm_dir, llvm_config_path) else: raise Exception("Building clang using LLVM binary not possible. Please invoke cpt without --with-binary-llvm and --with-llvm-tar flags") if tar_required: - - llvm_flags = "-DLLVM_BINARY_DIR={0} -DLLVM_CONFIG={1} -DLLVM_LIBRARY_DIR={2} -DLLVM_MAIN_INCLUDE_DIR={3} -DLLVM_TABLEGEN_EXE={4} \ - -DLLVM_TOOLS_BINARY_DIR={5} -DLLVM_TOOL_CLING_BUILD=ON".format(llvm_dir, llvm_config_path, - os.path.join(llvm_dir, 'lib'), os.path.join(llvm_dir, 'include'), os.path.join(llvm_dir, 'bin', 'llvm-tblgen'), - os.path.join(llvm_dir, 'bin')) - if args['verbose']: - llvm_flags += "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" + llvm_flags = llvm_flag_setter(llvm_dir, llvm_config_path) if DIST=="Ubuntu" and REV=='16.04' and is_os_64bit(): download_link = 'http://releases.llvm.org/5.0.2/clang+llvm-5.0.2-x86_64-linux-gnu-ubuntu-16.04.tar.xz' exec_subprocess_call('wget %s' % download_link, workdir) From ebf065a905d5bbb9df1f90f9fe9624b96d607b41 Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Mon, 27 Jun 2022 21:54:25 +0200 Subject: [PATCH 058/104] [ntuple] Clarify 'compression settings' in specification (NFC) --- tree/ntuple/v7/doc/specifications.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tree/ntuple/v7/doc/specifications.md b/tree/ntuple/v7/doc/specifications.md index 57335c961d8b8..b0b86eb956bbe 100644 --- a/tree/ntuple/v7/doc/specifications.md +++ b/tree/ntuple/v7/doc/specifications.md @@ -42,6 +42,10 @@ _String_: A string is stored as a 32bit unsigned integer indicating the length o followed by the characters. Strings are ASCII encoded; every character is a signed 8bit integer. +_Compression settings_: A 32bit integer containing both a compression algorithm and the compression level. +The compression settings are encoded according to this forumlar: $$ settings = algorithm * 100 + level $$ +See Compression.[h/cxx] for details and available algorithms. + The meta-data envelope defines additional basic types (see below). @@ -435,7 +439,7 @@ The order of items corresponds to the cluster IDs as defined by the cluster grou Every item of the top-most list frame consists of an outer list frame where every item corresponds to a column. Every item of the outer list frame is an inner list frame whose items correspond to the pages of the column in the cluster. -The inner list is followed by a 64bit unsigned integer element offset and the 32bit compression settings. +The inner list is followed by a 64bit unsigned integer element offset and the 32bit compression settings (see Section "Basic Types"). Note that the size of the inner list frame includes the element offset and compression settings. The order of the outer items must match the order of the columns as specified in the cluster summary and column groups. For a complete cluster (covering all original columns), the order is given by the column IDs (small to large). From a483a2bc75552301e3347c56898df07b95fe45f9 Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Tue, 28 Jun 2022 11:24:19 +0200 Subject: [PATCH 059/104] [ntuple] Fix typo in specification (NFC) Co-authored-by: Sebastien Binet --- tree/ntuple/v7/doc/specifications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tree/ntuple/v7/doc/specifications.md b/tree/ntuple/v7/doc/specifications.md index b0b86eb956bbe..f23957986d81a 100644 --- a/tree/ntuple/v7/doc/specifications.md +++ b/tree/ntuple/v7/doc/specifications.md @@ -43,7 +43,7 @@ followed by the characters. Strings are ASCII encoded; every character is a signed 8bit integer. _Compression settings_: A 32bit integer containing both a compression algorithm and the compression level. -The compression settings are encoded according to this forumlar: $$ settings = algorithm * 100 + level $$ +The compression settings are encoded according to this formula: $$ settings = algorithm * 100 + level $$ See Compression.[h/cxx] for details and available algorithms. The meta-data envelope defines additional basic types (see below). From 34b277324dc4143a627432eedabf278ec3a40908 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 10:09:24 +0200 Subject: [PATCH 060/104] Use nullptr and TString::Form in TGraphPolargram Replace plain Form by TString form; form.Form(...) --- graf2d/graf/src/TGraphPolar.cxx | 8 +- graf2d/graf/src/TGraphPolargram.cxx | 124 ++++++++++++++-------------- 2 files changed, 65 insertions(+), 67 deletions(-) diff --git a/graf2d/graf/src/TGraphPolar.cxx b/graf2d/graf/src/TGraphPolar.cxx index 20cd525653ff9..180d2c0993452 100644 --- a/graf2d/graf/src/TGraphPolar.cxx +++ b/graf2d/graf/src/TGraphPolar.cxx @@ -64,7 +64,7 @@ ClassImp(TGraphPolar); /// TGraphPolar default constructor. TGraphPolar::TGraphPolar() : TGraphErrors(), - fOptionAxis(kFALSE),fPolargram(0),fXpol(0),fYpol(0) + fOptionAxis(kFALSE),fPolargram(nullptr),fXpol(nullptr),fYpol(nullptr) { } @@ -80,7 +80,7 @@ TGraphPolar::TGraphPolar() : TGraphErrors(), TGraphPolar::TGraphPolar(Int_t n, const Double_t* theta, const Double_t* r, const Double_t *etheta, const Double_t* er) : TGraphErrors(n,theta,r,etheta,er), - fOptionAxis(kFALSE),fPolargram(0),fXpol(0),fYpol(0) + fOptionAxis(kFALSE),fPolargram(nullptr),fXpol(nullptr),fYpol(nullptr) { SetEditable(kFALSE); } @@ -90,8 +90,8 @@ TGraphPolar::TGraphPolar(Int_t n, const Double_t* theta, const Double_t* r, TGraphPolar::~TGraphPolar() { - delete []fXpol; - delete []fYpol; + delete [] fXpol; + delete [] fYpol; } //////////////////////////////////////////////////////////////////////////////// diff --git a/graf2d/graf/src/TGraphPolargram.cxx b/graf2d/graf/src/TGraphPolargram.cxx index 401649c111af9..c404d12ddb6f3 100644 --- a/graf2d/graf/src/TGraphPolargram.cxx +++ b/graf2d/graf/src/TGraphPolargram.cxx @@ -61,7 +61,7 @@ TGraphPolargram::TGraphPolargram(const char* name, Double_t rmin, Double_t rmax, Init(); fNdivRad = 508; fNdivPol = 508; - fPolarLabels = NULL; + fPolarLabels = nullptr; fRwrmax = rmax; fRwrmin = rmin; fRwtmin = tmin; @@ -77,7 +77,7 @@ TGraphPolargram::TGraphPolargram(const char* name): Init(); fNdivRad = 0; fNdivPol = 0; - fPolarLabels = NULL; + fPolarLabels = nullptr; fRwrmax = 1; fRwrmin = 0; fRwtmax = 0; @@ -89,7 +89,7 @@ TGraphPolargram::TGraphPolargram(const char* name): TGraphPolargram::~TGraphPolargram() { - if (fPolarLabels != NULL) delete [] fPolarLabels; + if (fPolarLabels) delete [] fPolarLabels; } //////////////////////////////////////////////////////////////////////////////// @@ -423,74 +423,74 @@ void TGraphPolargram::PaintPolarDivisions(Bool_t optionLabels) Double_t sinthetas = (1+fPolarOffset)*sintheta; Double_t corr = 0.01; - TLatex *textangular = new TLatex(); - textangular->SetTextColor(GetPolarColorLabel()); - textangular->SetTextFont(GetPolarLabelFont()); + TLatex textangular; + textangular.SetTextColor(GetPolarColorLabel()); + textangular.SetTextFont(GetPolarLabelFont()); - const char* form = (char *)" "; + TString form = " "; TGaxis axis; if (TestBit(TGraphPolargram::kLabelOrtho)) { // Polar numbers are aligned with their axis. - if(fPolarLabels == NULL && optionLabels){; + if(!fPolarLabels && optionLabels){; if (fRadian) { // Radian case. ReduceFraction(2*i, ndivMajor, rnum, rden); // Reduces the fraction. - if (rnum == 0) form = Form("%d",rnum); - if (rnum == 1 && rden == 1) form = Form("#pi"); - if (rnum == 1 && rden != 1) form = Form("#frac{#pi}{%d}",rden); - if (rnum != 1 && rden == 1 && i !=0) form= Form("%d#pi",rnum); - if (rnum != 1 && rden != 1) form = Form("#frac{%d#pi}{%d}",rnum,rden); - textangular->SetTextAlign(FindAlign(theta)); - textangular->PaintLatex(costhetas, + if (rnum == 0) form.Form("%d",rnum); + if (rnum == 1 && rden == 1) form = "#pi"; + if (rnum == 1 && rden != 1) form.Form("#frac{#pi}{%d}",rden); + if (rnum != 1 && rden == 1 && i !=0) form.Form("%d#pi",rnum); + if (rnum != 1 && rden != 1) form.Form("#frac{%d#pi}{%d}",rnum,rden); + textangular.SetTextAlign(FindAlign(theta)); + textangular.PaintLatex(costhetas, sinthetas, FindTextAngle(theta), - GetPolarLabelSize(), form); + GetPolarLabelSize(), form.Data()); } else { // Any other cases: numbers are aligned with their axis. - form = Form("%5.3g",txtval); - axis.LabelsLimits(form,first,last); - TString s = Form("%s",form); + form.Form("%5.3g",txtval); + axis.LabelsLimits(form.Data(),first,last); + TString s = form; if (first != 0) s.Remove(0, first); - textangular->SetTextAlign(FindAlign(theta)); - textangular->PaintLatex(costhetas, + textangular.SetTextAlign(FindAlign(theta)); + textangular.PaintLatex(costhetas, sinthetas, FindTextAngle(theta), GetPolarLabelSize(), s); } } else if (fPolarLabels){ // print the specified polar labels - textangular->SetTextAlign(FindAlign(theta)); - textangular->PaintLatex(costhetas,sinthetas,FindTextAngle(theta), + textangular.SetTextAlign(FindAlign(theta)); + textangular.PaintLatex(costhetas,sinthetas,FindTextAngle(theta), GetPolarLabelSize(), fPolarLabels[i]); } } else { // Polar numbers are shown horizontally. - if(fPolarLabels == NULL && optionLabels){ + if(!fPolarLabels && optionLabels){ if (fRadian) { // Radian case ReduceFraction(2*i, ndivMajor, rnum, rden); - if (rnum == 0) form = Form("%d",rnum); - if (rnum == 1 && rden == 1) form = Form("#pi"); - if (rnum == 1 && rden != 1) form = Form("#frac{#pi}{%d}",rden); - if (rnum != 1 && rden == 1 && i !=0) form = Form("%d#pi",rnum); - if (rnum != 1 && rden != 1) form = Form("#frac{%d#pi}{%d}",rnum,rden); + if (rnum == 0) form.Form("%d",rnum); + if (rnum == 1 && rden == 1) form = "#pi"; + if (rnum == 1 && rden != 1) form.Form("#frac{#pi}{%d}",rden); + if (rnum != 1 && rden == 1 && i !=0) form.Form("%d#pi",rnum); + if (rnum != 1 && rden != 1) form.Form("#frac{%d#pi}{%d}",rnum,rden); if(theta >= 3*TMath::Pi()/12.0 && theta < 2*TMath::Pi()/3.0) corr=0.04; - textangular->SetTextAlign(FindAlign(theta)); - textangular->PaintLatex(costhetas,corr+sinthetas,0, - GetPolarLabelSize(),form); + textangular.SetTextAlign(FindAlign(theta)); + textangular.PaintLatex(costhetas,corr+sinthetas,0, + GetPolarLabelSize(),form.Data()); } else { // Any other cases where numbers are shown horizontally. - form = Form("%5.3g",txtval); - axis.LabelsLimits(form,first,last); - TString s = Form("%s",form); + form.Form("%5.3g",txtval); + axis.LabelsLimits(form.Data(),first,last); + TString s = form; if (first != 0) s.Remove(0, first); if(theta >= 3*TMath::Pi()/12.0 && theta < 2*TMath::Pi()/3.0) corr=0.04; - textangular->SetTextAlign(FindAlign(theta)); - textangular->PaintLatex(costhetas, //j'ai efface des offset la + textangular.SetTextAlign(FindAlign(theta)); + textangular.PaintLatex(costhetas, //j'ai efface des offset la corr+sinthetas,0,GetPolarLabelSize(),s); } } else if (fPolarLabels) { // print the specified polar labels - textangular->SetTextAlign(FindAlign(theta)); - textangular->PaintText(costhetas,sinthetas,fPolarLabels[i]); + textangular.SetTextAlign(FindAlign(theta)); + textangular.PaintText(costhetas,sinthetas,fPolarLabels[i]); } } TAttLine::Modify(); @@ -510,7 +510,6 @@ void TGraphPolargram::PaintPolarDivisions(Bool_t optionLabels) TAttLine::SetLineStyle(1); TAttLine::Modify(); gPad->PaintLine(0.,0.,costheta,sintheta); - delete textangular; // Add minor lines w/o text. Int_t oldLineStyle = GetLineStyle(); TAttLine::SetLineStyle(2); //Minor lines always in this style. @@ -539,45 +538,45 @@ void TGraphPolargram::PaintPolarDivisions(Bool_t optionLabels) Double_t sinthetas = (1+fPolarOffset)*sintheta; Double_t corr = 0.01; - TLatex *textangular = new TLatex(); - textangular->SetTextColor(GetPolarColorLabel()); - textangular->SetTextFont(GetPolarLabelFont()); + TLatex textangular; + textangular.SetTextColor(GetPolarColorLabel()); + textangular.SetTextFont(GetPolarLabelFont()); - const char* form = (char *)" "; + TString form = " "; TGaxis axis; if (TestBit(TGraphPolargram::kLabelOrtho)) { - if(fPolarLabels==NULL && optionLabels){ + if(!fPolarLabels && optionLabels){ // Polar numbers are aligned with their axis. - form = Form("%5.3g",txtval); - axis.LabelsLimits(form,first,last); - TString s = Form("%s",form); + form.Form("%5.3g",txtval); + axis.LabelsLimits(form.Data(),first,last); + TString s = form; if (first != 0) s.Remove(0, first); - textangular->SetTextAlign(FindAlign(theta)); - textangular->PaintLatex(costhetas, + textangular.SetTextAlign(FindAlign(theta)); + textangular.PaintLatex(costhetas, sinthetas, FindTextAngle(theta), GetPolarLabelSize(), s); } else if (fPolarLabels){ // print the specified polar labels - textangular->SetTextAlign(FindAlign(theta)); - textangular->PaintText(costhetas,sinthetas,fPolarLabels[i]); + textangular.SetTextAlign(FindAlign(theta)); + textangular.PaintText(costhetas,sinthetas,fPolarLabels[i]); } } else { - if(fPolarLabels==NULL && optionLabels){ + if(!fPolarLabels && optionLabels){ // Polar numbers are shown horizontally. - form = Form("%5.3g",txtval); - axis.LabelsLimits(form,first,last); - TString s = Form("%s",form); + form.Form("%5.3g",txtval); + axis.LabelsLimits(form.Data(),first,last); + TString s = form; if (first != 0) s.Remove(0, first); if(theta >= 3*TMath::Pi()/12.0 && theta < 2*TMath::Pi()/3.0) corr=0.04; - textangular->SetTextAlign(FindAlign(theta)); - textangular->PaintLatex(costhetas, + textangular.SetTextAlign(FindAlign(theta)); + textangular.PaintLatex(costhetas, corr+sinthetas,0,GetPolarLabelSize(),s); } else if (fPolarLabels){ // print the specified polar labels - textangular->SetTextAlign(FindAlign(theta)); - textangular->PaintText(costhetas,sinthetas,fPolarLabels[i]); + textangular.SetTextAlign(FindAlign(theta)); + textangular.PaintText(costhetas,sinthetas,fPolarLabels[i]); } } @@ -597,7 +596,6 @@ void TGraphPolargram::PaintPolarDivisions(Bool_t optionLabels) TAttLine::SetLineStyle(1); TAttLine::Modify(); gPad->PaintLine(0.,0.,costheta,sintheta); - delete textangular; // Add minor lines w/o text. Int_t oldLineStyle = GetLineStyle(); TAttLine::SetLineStyle(2); //Minor lines always in this style. @@ -793,9 +791,9 @@ void TGraphPolargram::SetNdivRadial(Int_t ndiv) void TGraphPolargram::SetPolarLabel(Int_t div, const TString & label) { - if(fPolarLabels == NULL) + if(!fPolarLabels) fPolarLabels = new TString[fNdivPol]; - fPolarLabels[div]=label; + fPolarLabels[div] = label; if (gPad) gPad->Modified(); } From 5048abe98ace2304bbad6531030f46c4de585fb2 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 11:13:06 +0200 Subject: [PATCH 061/104] Use std::vector for TLatex::fTabSize Ensure proper allocation, destroy, copy of this data Had problems in copy and assign operators --- graf2d/graf/inc/TLatex.h | 94 +++++++++++++++++--------------------- graf2d/graf/src/TLatex.cxx | 73 ++++++++++------------------- 2 files changed, 66 insertions(+), 101 deletions(-) diff --git a/graf2d/graf/inc/TLatex.h b/graf2d/graf/inc/TLatex.h index abfe15355050a..cf4e1e26499fe 100644 --- a/graf2d/graf/inc/TLatex.h +++ b/graf2d/graf/inc/TLatex.h @@ -13,7 +13,7 @@ #include "TText.h" #include "TAttLine.h" - +#include class TLatex : public TText, public TAttLine { protected: @@ -26,12 +26,6 @@ class TLatex : public TText, public TAttLine { Int_t fColor,fFont; }; -//////////////////////////////////////////////////////////////////////////////// -/// @brief TLatex helper struct holding the dimensions of a piece of text. - struct FormSize_t { - Double_t fWidth, fOver, fUnder; - }; - //////////////////////////////////////////////////////////////////////////////// /// @class TLatexFormSize /// @brief TLatex helper class used to compute the size of a portion of a formula. @@ -42,7 +36,7 @@ class TLatex : public TText, public TAttLine { public: TLatexFormSize() = default; - TLatexFormSize(Double_t x, Double_t y1, Double_t y2) : fWidth(x), fOver(y1), fUnder(y2) { } // constructor + TLatexFormSize(Double_t width, Double_t over, Double_t under) : fWidth(width), fOver(over), fUnder(under) { } // constructor // definition of operators + and += TLatexFormSize operator+(TLatexFormSize f) @@ -65,64 +59,62 @@ class TLatex : public TText, public TAttLine { inline Double_t Height() const { return fOver+fUnder; } }; - Double_t fFactorSize; /// fTabSize; ///AbsPixeltoX(Int_t(fs.Width())) - gPad->AbsPixeltoX(0)); } @@ -2602,7 +2584,7 @@ void TLatex::GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle) } else { const Char_t *text = newText.Data() ; TLatexFormSize fs = FirstParse(GetTextAngle(),GetTextSize(),text); - delete[] fTabSize; + fTabSize.clear(); w = (UInt_t)fs.Width(); h = (UInt_t)fs.Height(); } @@ -2636,7 +2618,7 @@ Double_t TLatex::GetYsize() Double_t angsav = fTextAngle; TLatexFormSize fs = FirstParse(0,GetTextSize(),text); fTextAngle = angsav; - delete[] fTabSize; + fTabSize.clear(); return TMath::Abs(gPad->AbsPixeltoY(Int_t(fs.Height())) - gPad->AbsPixeltoY(0)); } @@ -2645,8 +2627,13 @@ Double_t TLatex::GetYsize() TLatex::TLatexFormSize TLatex::Readfs() { - fPos--; - TLatexFormSize result(fTabSize[fPos].fWidth,fTabSize[fPos].fOver,fTabSize[fPos].fUnder); + if (fTabSize.empty()) { + Error("Readfs", "No data in fTabSize stack"); + return TLatexFormSize(0,0,0); + } + + TLatexFormSize result = fTabSize.back(); + fTabSize.pop_back(); return result; } @@ -2655,21 +2642,7 @@ TLatex::TLatexFormSize TLatex::Readfs() void TLatex::Savefs(TLatex::TLatexFormSize *fs) { - fTabSize[fPos].fWidth = fs->Width(); - fTabSize[fPos].fOver = fs->Over(); - fTabSize[fPos].fUnder = fs->Under(); - fPos++; - if (fPos>=fTabMax) { - // allocate more memory - FormSize_t *temp = new FormSize_t[fTabMax+100]; - // copy array - memcpy(temp,fTabSize,fTabMax*sizeof(FormSize_t)); - fTabMax += 100; - // free previous array - delete [] fTabSize; - // swap pointers - fTabSize = temp; - } + fTabSize.emplace_back(*fs); } //////////////////////////////////////////////////////////////////////////////// From f6658fab13d7c09523530ebc1f9ebce20e12238b Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 11:30:32 +0200 Subject: [PATCH 062/104] Use vector for columnWidths in TLegend --- graf2d/graf/src/TLegend.cxx | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/graf2d/graf/src/TLegend.cxx b/graf2d/graf/src/TLegend.cxx index e8cbe7224aed9..61f8c765ae6de 100644 --- a/graf2d/graf/src/TLegend.cxx +++ b/graf2d/graf/src/TLegend.cxx @@ -200,7 +200,7 @@ End_Macro TLegend::TLegend(): TPave(0.3,0.15,0.3,0.15,4,"brNDC"), TAttText(12,0,1,gStyle->GetLegendFont(),0) { - fPrimitives = 0; + fPrimitives = nullptr; SetDefaults(); SetBorderSize(gStyle->GetLegendBorderSize()); SetFillColor(gStyle->GetLegendFillColor()); @@ -276,7 +276,7 @@ TLegend::TLegend( Double_t w, Double_t h, const char *header, Option_t *option) /// Copy constructor. TLegend::TLegend( const TLegend &legend ) : TPave(legend), TAttText(legend), - fPrimitives(0) + fPrimitives(nullptr) { if (legend.fPrimitives) { fPrimitives = new TList(); @@ -310,9 +310,10 @@ TLegend& TLegend::operator=(const TLegend &lg) TLegend::~TLegend() { - if (fPrimitives) fPrimitives->Delete(); + if (fPrimitives) + fPrimitives->Delete(); delete fPrimitives; - fPrimitives = 0; + fPrimitives = nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -516,15 +517,14 @@ TLegendEntry *TLegend::GetEntry() const const char *TLegend::GetHeader() const { - if ( !fPrimitives ) return 0; + if ( !fPrimitives ) return nullptr; TIter next(fPrimitives); - TLegendEntry *first; // header is always the first entry - if (( first = (TLegendEntry*)next() )) { + if (auto first = (TLegendEntry*)next()) { TString opt = first->GetOption(); opt.ToLower(); if ( opt.Contains("h") ) return first->GetLabel(); } - return 0; + return nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -637,8 +637,7 @@ void TLegend::PaintPrimitives() textsize = GetTextSize(); } Bool_t autosize = kFALSE; - Double_t* columnWidths = new Double_t[fNColumns]; - memset(columnWidths, 0, fNColumns*sizeof(Double_t)); + std::vector columnWidths(fNColumns, 0.); if ( textsize == 0 ) { autosize = kTRUE; @@ -691,10 +690,10 @@ void TLegend::PaintPrimitives() // don't want to ruin initialisation of these variables later on { TIter next(fPrimitives); - TLegendEntry *entry; Int_t iColumn = 0; - memset(columnWidths, 0, fNColumns*sizeof(Double_t)); - while (( entry = (TLegendEntry *)next() )) { + for (Int_t k = 0; k < fNColumns; ++k) + columnWidths[k] = 0.; + while (auto entry = (TLegendEntry *)next()) { TLatex entrytex( 0, 0, entry->GetLabel() ); entrytex.SetNDC(); Style_t tfont = entry->GetTextFont(); @@ -1012,7 +1011,6 @@ void TLegend::PaintPrimitives() if ( opt.Contains("p")) entrymarker.Paint(); } SetTextSize(save_textsize); - delete [] columnWidths; } //////////////////////////////////////////////////////////////////////////////// @@ -1030,9 +1028,9 @@ void TLegend::Print( Option_t* option ) const void TLegend::RecursiveRemove(TObject *obj) { TIter next(fPrimitives); - TLegendEntry *entry; - while (( entry = (TLegendEntry *)next() )) { - if (entry->GetObject() == obj) entry->SetObject((TObject*)0); + while (auto entry = (TLegendEntry *)next()) { + if (entry->GetObject() == obj) + entry->SetObject((TObject *)nullptr); } } From 949a2f9bea09f147ead71440c1a3bf3a36af9dae Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 13:15:17 +0200 Subject: [PATCH 063/104] Fix bug in TPie copy constructor One cannot copy pointers on pie slices, but have to copy values. Implement TPieSlice::Copy function for that --- graf2d/graf/inc/TPieSlice.h | 6 ++++-- graf2d/graf/src/TPie.cxx | 5 ++--- graf2d/graf/src/TPieSlice.cxx | 20 ++++++++++++++++++-- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/graf2d/graf/inc/TPieSlice.h b/graf2d/graf/inc/TPieSlice.h index 18f62c81b4d6a..dd83c9084451e 100644 --- a/graf2d/graf/inc/TPieSlice.h +++ b/graf2d/graf/inc/TPieSlice.h @@ -30,14 +30,16 @@ class TPieSlice : public TNamed, public TAttFill, public TAttLine { TPieSlice(const char *, const char *, TPie*, Double_t val=0); virtual ~TPieSlice() {} + void Copy(TObject &slice) const override; Int_t DistancetoPrimitive(Int_t,Int_t) override; - Double_t GetRadiusOffset(); - Double_t GetValue(); + Double_t GetRadiusOffset() const; + Double_t GetValue() const; void SavePrimitive(std::ostream &out, Option_t *opts="") override; void SetIsActive(Bool_t is) { fIsActive = is; } void SetRadiusOffset(Double_t); // *MENU* void SetValue(Double_t); // *MENU* + friend class TPie; ClassDefOverride(TPieSlice,1) // Slice of a pie chart graphics class diff --git a/graf2d/graf/src/TPie.cxx b/graf2d/graf/src/TPie.cxx index 88a83ded84a6c..0e0c8c01c56cf 100644 --- a/graf2d/graf/src/TPie.cxx +++ b/graf2d/graf/src/TPie.cxx @@ -145,9 +145,8 @@ TPie::TPie(const TPie &cpy) : TNamed(cpy), TAttText(cpy) { Init(cpy.fNvals, cpy.fAngularOffset, cpy.fX, cpy.fY, cpy.fRadius); - for (Int_t i=0;iCopy(*fPieSlices[i]); } //////////////////////////////////////////////////////////////////////////////// diff --git a/graf2d/graf/src/TPieSlice.cxx b/graf2d/graf/src/TPieSlice.cxx index e4e5c64fcc02e..2eabfc7cd75ba 100644 --- a/graf2d/graf/src/TPieSlice.cxx +++ b/graf2d/graf/src/TPieSlice.cxx @@ -65,7 +65,7 @@ Int_t TPieSlice::DistancetoPrimitive(Int_t /*px*/, Int_t /*py*/) //////////////////////////////////////////////////////////////////////////////// /// return the value of the offset in radial direction for this slice. -Double_t TPieSlice::GetRadiusOffset() +Double_t TPieSlice::GetRadiusOffset() const { return fRadiusOffset; } @@ -73,7 +73,7 @@ Double_t TPieSlice::GetRadiusOffset() //////////////////////////////////////////////////////////////////////////////// /// Return the value of this slice. -Double_t TPieSlice::GetValue() +Double_t TPieSlice::GetValue() const { return fValue; } @@ -108,3 +108,19 @@ void TPieSlice::SetValue(Double_t val) fPie->MakeSlices(kTRUE); } + +//////////////////////////////////////////////////////////////////////////////// +/// Copy TPieSlice + +void TPieSlice::Copy(TObject &obj) const +{ + auto &slice = (TPieSlice&)obj; + + TNamed::Copy(slice); + TAttLine::Copy(slice); + TAttFill::Copy(slice); + + slice.SetValue(GetValue()); + slice.SetRadiusOffset(GetRadiusOffset()); +} + From 56f6ad1c8901f189d02904b1d9d5c3d9085a9d41 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 13:25:48 +0200 Subject: [PATCH 064/104] Use nullptr in graf2d/graf classes --- graf2d/graf/src/TCandle.cxx | 15 ++++---------- graf2d/graf/src/TCutG.cxx | 20 +++++++++---------- graf2d/graf/src/TGraphQQ.cxx | 17 ++++++++-------- graf2d/graf/src/TLatex.cxx | 36 +++++++++++++++++----------------- graf2d/graf/src/TPaveStats.cxx | 8 ++++---- graf2d/graf/src/TPaveText.cxx | 5 ++--- graf2d/graf/src/TPolyLine.cxx | 22 ++++++++++----------- 7 files changed, 57 insertions(+), 66 deletions(-) diff --git a/graf2d/graf/src/TCandle.cxx b/graf2d/graf/src/TCandle.cxx index ece8ae9bc6509..07d57d6131d6f 100644 --- a/graf2d/graf/src/TCandle.cxx +++ b/graf2d/graf/src/TCandle.cxx @@ -392,7 +392,7 @@ void TCandle::Calculate() { Double_t max = -1e15; // Determining the quantiles - Double_t *prob = new Double_t[5]; + Double_t prob[5]; if (fWhiskerRange >= 1) { prob[0] = 1e-15; @@ -402,7 +402,6 @@ void TCandle::Calculate() { prob[4] = 0.5 + fWhiskerRange/2.; } - if (fBoxRange >= 1) { prob[1] = 1E-14; prob[3] = 1-1E-14; @@ -411,9 +410,9 @@ void TCandle::Calculate() { prob[3] = 0.5 + fBoxRange/2.; } - prob[2]=0.5; - Double_t *quantiles = new Double_t[5]; - quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.; quantiles[3] = 0.; quantiles[4] = 0.; + prob[2] = 0.5; + + Double_t quantiles[5] = { 0., 0., 0., 0., 0. }; if (!fIsRaw && fProj) { //Need a calculation for a projected histo if (((IsOption(kHistoLeft)) || (IsOption(kHistoRight)) || (IsOption(kHistoViolin))) && fProj->GetNbinsX() > 500) { // When using the histooption the number of bins of the projection is @@ -432,8 +431,6 @@ void TCandle::Calculate() { // into account as well, we need to ignore this! if (quantiles[0] >= quantiles[4] || quantiles[1] >= quantiles[3]) { - delete [] prob; - delete [] quantiles; return; } @@ -487,9 +484,6 @@ void TCandle::Calculate() { fMedianErr = 1.57*iqr/sqrt(fNDatapoints); } - delete [] prob; - delete [] quantiles; - //Doing the outliers and other single points to show if (GetCandleOption(5) > 0) { //Draw outliers TRandom2 random; @@ -660,7 +654,6 @@ void TCandle::Calculate() { } } - fIsCalculated = true; } diff --git a/graf2d/graf/src/TCutG.cxx b/graf2d/graf/src/TCutG.cxx index 31c9bc656d9a9..92c5c6621d7a2 100644 --- a/graf2d/graf/src/TCutG.cxx +++ b/graf2d/graf/src/TCutG.cxx @@ -98,8 +98,8 @@ ClassImp(TCutG); TCutG::TCutG() : TGraph() { - fObjectX = 0; - fObjectY = 0; + fObjectX = nullptr; + fObjectY = nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -120,8 +120,8 @@ TCutG::TCutG(const TCutG &cutg) TCutG::TCutG(const char *name, Int_t n) :TGraph(n) { - fObjectX = 0; - fObjectY = 0; + fObjectX = nullptr; + fObjectY = nullptr; SetName(name); delete gROOT->GetListOfSpecials()->FindObject(name); gROOT->GetListOfSpecials()->Add(this); @@ -161,8 +161,8 @@ TCutG::TCutG(const char *name, Int_t n) TCutG::TCutG(const char *name, Int_t n, const Float_t *x, const Float_t *y) :TGraph(n,x,y) { - fObjectX = 0; - fObjectY = 0; + fObjectX = nullptr; + fObjectY = nullptr; SetName(name); delete gROOT->GetListOfSpecials()->FindObject(name); gROOT->GetListOfSpecials()->Add(this); @@ -202,8 +202,8 @@ TCutG::TCutG(const char *name, Int_t n, const Float_t *x, const Float_t *y) TCutG::TCutG(const char *name, Int_t n, const Double_t *x, const Double_t *y) :TGraph(n,x,y) { - fObjectX = 0; - fObjectY = 0; + fObjectX = nullptr; + fObjectY = nullptr; SetName(name); delete gROOT->GetListOfSpecials()->FindObject(name); gROOT->GetListOfSpecials()->Add(this); @@ -403,7 +403,7 @@ void TCutG::SetVarX(const char *varx) { fVarX = varx; delete fObjectX; - fObjectX = 0; + fObjectX = nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -413,7 +413,7 @@ void TCutG::SetVarY(const char *vary) { fVarY = vary; delete fObjectY; - fObjectY = 0; + fObjectY = nullptr; } //////////////////////////////////////////////////////////////////////////////// diff --git a/graf2d/graf/src/TGraphQQ.cxx b/graf2d/graf/src/TGraphQQ.cxx index fe242b0092214..f11ed6f725590 100644 --- a/graf2d/graf/src/TGraphQQ.cxx +++ b/graf2d/graf/src/TGraphQQ.cxx @@ -118,8 +118,8 @@ TGraphQQ::TGraphQQ(Int_t n, Double_t *x) TMath::Sort(n, x, index, kFALSE); for (Int_t i=0; i: "< "<: "< "<: "< "<: "< "<: "< "<GetOptFit(); fOptStat = gStyle->GetOptStat(); } @@ -239,7 +239,7 @@ TPaveStats::TPaveStats(): TPaveText() TPaveStats::TPaveStats(Double_t x1, Double_t y1,Double_t x2, Double_t y2, Option_t *option) :TPaveText(x1,y1,x2,y2,option) { - fParent = 0; + fParent = nullptr; fOptFit = gStyle->GetOptFit(); fOptStat = gStyle->GetOptStat(); SetFitFormat(gStyle->GetFitFormat()); @@ -349,7 +349,7 @@ void TPaveStats::Paint(Option_t *option) TIter next(fLines); Double_t longest = 0, titlelength = 0; Double_t w, wtok[2]; - char *st, *sl=0; + char *st, *sl = nullptr; if (textsize == 0) { textsize = 0.92*yspace/(y2 - y1); titlesize = textsize; @@ -385,7 +385,7 @@ void TPaveStats::Paint(Option_t *option) if (titlelength > 0.98*dx) titlesize *= 0.98*dx/titlelength; latex->SetTextFont(tfont); } - delete [] sl; sl = 0; + delete [] sl; sl = nullptr; } } longest = wtok[0]+wtok[1]+2.*margin; diff --git a/graf2d/graf/src/TPaveText.cxx b/graf2d/graf/src/TPaveText.cxx index 1a097a66e1a7a..5ed876879253c 100644 --- a/graf2d/graf/src/TPaveText.cxx +++ b/graf2d/graf/src/TPaveText.cxx @@ -597,7 +597,6 @@ void TPaveText::ReadFile(const char *filename, Option_t *option, Int_t nlines, I { Int_t ival; Float_t val; - TText *lastline = 0; TString opt = option; if (!opt.Contains("+")) { Clear(); @@ -620,7 +619,7 @@ void TPaveText::ReadFile(const char *filename, Option_t *option, Int_t nlines, I const int linesize = 255; char currentline[linesize]; - char *ss, *sclose, *s= 0; + char *ss, *sclose, *s = nullptr; Int_t kline = 0; while (1) { @@ -633,7 +632,7 @@ void TPaveText::ReadFile(const char *filename, Option_t *option, Int_t nlines, I sclose = strstr(ss,")"); if (!sclose) continue; *sclose = 0; - lastline = (TText*)fLines->Last(); + TText *lastline = (TText*)fLines->Last(); if (!lastline) continue; if (strstr(ss,"Color(")) { sscanf(ss+6,"%d",&ival); diff --git a/graf2d/graf/src/TPolyLine.cxx b/graf2d/graf/src/TPolyLine.cxx index fc53a99a63b3c..eb58fd3d1cb1a 100644 --- a/graf2d/graf/src/TPolyLine.cxx +++ b/graf2d/graf/src/TPolyLine.cxx @@ -47,8 +47,8 @@ End_Macro TPolyLine::TPolyLine(): TObject() { fN = 0; - fX = 0; - fY = 0; + fX = nullptr; + fY = nullptr; fLastPoint = -1; } @@ -64,7 +64,7 @@ TPolyLine::TPolyLine(Int_t n, Option_t *option) if (n <= 0) { fN = 0; fLastPoint = -1; - fX = fY = 0; + fX = fY = nullptr; return; } fN = n; @@ -109,7 +109,7 @@ TPolyLine::TPolyLine(Int_t n, Double_t *x, Double_t *y, Option_t *option) if (n <= 0) { fN = 0; fLastPoint = -1; - fX = fY = 0; + fX = fY = nullptr; return; } fN = n; @@ -146,8 +146,8 @@ TPolyLine::~TPolyLine() TPolyLine::TPolyLine(const TPolyLine &polyline) : TObject(polyline), TAttLine(polyline), TAttFill(polyline) { fN = 0; - fX = 0; - fY = 0; + fX = nullptr; + fY = nullptr; fLastPoint = -1; ((TPolyLine&)polyline).Copy(*this); } @@ -168,8 +168,8 @@ void TPolyLine::Copy(TObject &obj) const ((TPolyLine&)obj).fY = new Double_t[fN]; for (Int_t i=0; i Date: Tue, 28 Jun 2022 13:27:03 +0200 Subject: [PATCH 065/104] Fix memory leak reading old version of TPolyLine Probably, is very rare use-case --- graf2d/graf/src/TPolyLine.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/graf2d/graf/src/TPolyLine.cxx b/graf2d/graf/src/TPolyLine.cxx index eb58fd3d1cb1a..e781b22059531 100644 --- a/graf2d/graf/src/TPolyLine.cxx +++ b/graf2d/graf/src/TPolyLine.cxx @@ -772,6 +772,8 @@ void TPolyLine::Streamer(TBuffer &b) b.CheckByteCount(R__s, R__c, TPolyLine::IsA()); //====end of old versions + delete [] x; + delete [] y; } else { b.WriteClassBuffer(TPolyLine::Class(),this); } From e728d6984b47045562db8cb0b11957087186f5bf Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 13:52:46 +0200 Subject: [PATCH 066/104] Use stack TLine and TLatex objects when drawing TGaxis Simplify cleanup, no need to call `goto L210` only for cleanup. Use nullptr --- graf2d/graf/src/TGaxis.cxx | 231 ++++++++++++++++++------------------- 1 file changed, 113 insertions(+), 118 deletions(-) diff --git a/graf2d/graf/src/TGaxis.cxx b/graf2d/graf/src/TGaxis.cxx index 1ad86294c9ebb..a0c767f4c5fa2 100644 --- a/graf2d/graf/src/TGaxis.cxx +++ b/graf2d/graf/src/TGaxis.cxx @@ -712,11 +712,11 @@ TGaxis::TGaxis(): TLine(), TAttText(11,0,1,62,0.040) fTitle = ""; fTimeFormat = ""; fFunctionName= ""; - fFunction = 0; - fAxis = 0; + fFunction = nullptr; + fAxis = nullptr; fNdiv = 0; fNModLabs = 0; - fModLabs = 0; + fModLabs = nullptr; fWmin = 0.; fWmax = 0.; } @@ -734,7 +734,7 @@ TGaxis::TGaxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, fWmax = wmax; fNdiv = ndiv; fNModLabs = 0; - fModLabs = 0; + fModLabs = nullptr; fGridLength = gridlength; fLabelOffset = 0.005; fLabelSize = 0.040; @@ -748,8 +748,8 @@ TGaxis::TGaxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, fTitle = ""; fTimeFormat = ""; fFunctionName= ""; - fFunction = 0; - fAxis = 0; + fFunction = nullptr; + fAxis = nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -773,7 +773,7 @@ TGaxis::TGaxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, fFunctionName= funcname; fNdiv = ndiv; fNModLabs = 0; - fModLabs = 0; + fModLabs = nullptr; fGridLength = gridlength; fLabelOffset = 0.005; fLabelSize = 0.040; @@ -786,7 +786,7 @@ TGaxis::TGaxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, fName = ""; fTitle = ""; fTimeFormat = ""; - fAxis = 0; + fAxis = nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -1037,7 +1037,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma char chlabel[256]; char kchtemp[256]; char chcoded[64]; - TLine *linegrid; + TLine linegrid; TString timeformat; TString typolabel; time_t timelabel; @@ -1052,7 +1052,6 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma Double_t rwma = wmax; chtemp = &kchtemp[0]; label = &chlabel[0]; - linegrid = 0; fFunction = (TF1*)gROOT->GetFunction(fFunctionName.Data()); @@ -1111,7 +1110,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma fModLabs = ml; fNModLabs = fModLabs->GetSize(); } else { - fModLabs = 0; + fModLabs = nullptr; fNModLabs = 0; } } @@ -1124,11 +1123,10 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if (optionGrid) { if (gridlength == 0) gridlength = 0.8; - linegrid = new TLine(); - linegrid->SetLineColor(gStyle->GetGridColor()); - if (linegrid->GetLineColor() == 0) linegrid->SetLineColor(GetLineColor()); - linegrid->SetLineStyle(gStyle->GetGridStyle()); - linegrid->SetLineWidth(gStyle->GetGridWidth()); + linegrid.SetLineColor(gStyle->GetGridColor()); + if (linegrid.GetLineColor() == 0) linegrid.SetLineColor(GetLineColor()); + linegrid.SetLineStyle(gStyle->GetGridStyle()); + linegrid.SetLineWidth(gStyle->GetGridWidth()); } // No labels if the axis label offset is big. @@ -1334,7 +1332,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma return; } - TLatex *textaxis = new TLatex(); + TLatex textaxis; SetLineStyle(1); // axis line style Int_t TitleColor = GetTextColor(); Int_t TitleFont = GetTextFont(); @@ -1348,7 +1346,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma axis_length = TMath::Sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)); if (axis_length == 0) { Error(where, "length of axis is 0"); - goto L210; + return; } if (!optionNoopt || optionInt) { axis_lengthN = TMath::Sqrt((xx1-xx0)*(xx1-xx0)+(yy1-yy0)*(yy1-yy0)); @@ -1443,10 +1441,10 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma // No bining - if (ndiv == 0)goto L210; + if (ndiv == 0) return; if (wmin == wmax) { Error(where, "wmin (%f) == wmax (%f)", wmin, wmax); - goto L210; + return; } // Labels preparation: @@ -1456,24 +1454,24 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma charheight = GetLabelSize(); if (optionText && GetLabelFont()%10 != 3) charheight *= 0.66666; - textaxis->SetTextFont(GetLabelFont()); + textaxis.SetTextFont(GetLabelFont()); if ((GetLabelFont()%10 < 2) && optionLog) // force TLatex mode in PaintLatex - textaxis->SetTextFont((Int_t)(GetLabelFont()/10)*10+2); - textaxis->SetTextColor(GetLabelColor()); - textaxis->SetTextSize (charheight); - textaxis->SetTextAngle(GetTextAngle()); + textaxis.SetTextFont((Int_t)(GetLabelFont()/10)*10+2); + textaxis.SetTextColor(GetLabelColor()); + textaxis.SetTextSize (charheight); + textaxis.SetTextAngle(GetTextAngle()); if (GetLabelFont()%10 > 2) { charheight /= padh; } if (!optionUp && !optionDown && !optionY && !optionUnlab) { if (!drawGridOnly && optionText && ((ymin == ymax) || (xmin == xmax))) { - textaxis->SetTextAlign(32); + textaxis.SetTextAlign(32); optionText = 2; Int_t nl = fAxis->GetLast()-fAxis->GetFirst()+1; Double_t angle = 0; for (i=fAxis->GetFirst(); i<=fAxis->GetLast(); i++) { - textaxis->SetText(0,0,fAxis->GetBinLabel(i)); - if (textaxis->GetXsize() < (xmax-xmin)/nl) continue; + textaxis.SetText(0,0,fAxis->GetBinLabel(i)); + if (textaxis.GetXsize() < (xmax-xmin)/nl) continue; angle = -20; break; } @@ -1485,53 +1483,53 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if (fAxis->TestBit(TAxis::kLabelsVert)) angle = 90; if (fAxis->TestBit(TAxis::kLabelsUp)) angle = 20; if (fAxis->TestBit(TAxis::kLabelsDown)) angle =-20; - if (angle == 0) textaxis->SetTextAlign(23); - if (angle == -20) textaxis->SetTextAlign(12); - textaxis->SetTextAngle(angle); + if (angle == 0) textaxis.SetTextAlign(23); + if (angle == -20) textaxis.SetTextAlign(12); + textaxis.SetTextAngle(angle); Double_t s = -3; if (ymin == gPad->GetUymax()) { - if (angle == 0) textaxis->SetTextAlign(21); + if (angle == 0) textaxis.SetTextAlign(21); s = 3; } strncpy(chtemp, fAxis->GetBinLabel(i), 255); - if (fNModLabs) ChangeLabelAttributes(i, fAxis->GetLabels()->GetSize()-1, textaxis, chtemp); - textaxis->PaintLatex(fAxis->GetBinCenter(i), - ymin + s*fAxis->GetLabelOffset()*(gPad->GetUymax()-gPad->GetUymin()), - textaxis->GetTextAngle(), - textaxis->GetTextSize(), - chtemp); - if (fNModLabs) ResetLabelAttributes(textaxis); + if (fNModLabs) ChangeLabelAttributes(i, fAxis->GetLabels()->GetSize()-1, &textaxis, chtemp); + textaxis.PaintLatex(fAxis->GetBinCenter(i), + ymin + s*fAxis->GetLabelOffset()*(gPad->GetUymax()-gPad->GetUymin()), + textaxis.GetTextAngle(), + textaxis.GetTextSize(), + chtemp); + if (fNModLabs) ResetLabelAttributes(&textaxis); } else if ((!strcmp(fAxis->GetName(),"yaxis") && !gPad->TestBit(kHori)) || (!strcmp(fAxis->GetName(),"xaxis") && gPad->TestBit(kHori))) { Double_t s = -3; if (xmin == gPad->GetUxmax()) { - textaxis->SetTextAlign(12); + textaxis.SetTextAlign(12); s = 3; } if (autotoff) { UInt_t w,h; - textaxis->SetText(0.,0., fAxis->GetBinLabel(i)); - textaxis->GetBoundingBox(w,h); + textaxis.SetText(0.,0., fAxis->GetBinLabel(i)); + textaxis.GetBoundingBox(w,h); double scale=gPad->GetWw()*gPad->GetWNDC(); if (scale>0.0) toffset = TMath::Max(toffset,(double)w/scale); } strncpy(chtemp, fAxis->GetBinLabel(i), 255); - if (fNModLabs) ChangeLabelAttributes(i, fAxis->GetLabels()->GetSize()-1, textaxis, chtemp); - textaxis->PaintLatex(xmin + s*fAxis->GetLabelOffset()*(gPad->GetUxmax()-gPad->GetUxmin()), - fAxis->GetBinCenter(i), - 0, - textaxis->GetTextSize(), - chtemp); - if (fNModLabs) ResetLabelAttributes(textaxis); + if (fNModLabs) ChangeLabelAttributes(i, fAxis->GetLabels()->GetSize()-1, &textaxis, chtemp); + textaxis.PaintLatex(xmin + s*fAxis->GetLabelOffset()*(gPad->GetUxmax()-gPad->GetUxmin()), + fAxis->GetBinCenter(i), + 0, + textaxis.GetTextSize(), + chtemp); + if (fNModLabs) ResetLabelAttributes(&textaxis); } else { strncpy(chtemp, fAxis->GetBinLabel(i), 255); - if (fNModLabs) ChangeLabelAttributes(i, fAxis->GetLabels()->GetSize()-1, textaxis, chtemp); - textaxis->PaintLatex(xmin - 3*fAxis->GetLabelOffset()*(gPad->GetUxmax()-gPad->GetUxmin()), - ymin +(i-0.5)*(ymax-ymin)/nl, - 0, - textaxis->GetTextSize(), - chtemp); - if (fNModLabs) ResetLabelAttributes(textaxis); + if (fNModLabs) ChangeLabelAttributes(i, fAxis->GetLabels()->GetSize()-1, &textaxis, chtemp); + textaxis.PaintLatex(xmin - 3*fAxis->GetLabelOffset()*(gPad->GetUxmax()-gPad->GetUxmin()), + ymin +(i-0.5)*(ymax-ymin)/nl, + 0, + textaxis.GetTextSize(), + chtemp); + if (fNModLabs) ResetLabelAttributes(&textaxis); } } } @@ -1561,7 +1559,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if (cosphi*sinphi > 0) xalign = 1; if (cosphi*sinphi < 0) xalign = 3; } - textaxis->SetTextAlign(10*xalign+yalign); + textaxis.SetTextAlign(10*xalign+yalign); // Position of labels in Y if (x0 == x1) { @@ -1650,7 +1648,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma Rotate(xtick,0,cosphi ,sinphi,xx0,yy0 ,xpl2,ypl2); Rotate(xtick,grid_side*gridlength ,cosphi,sinphi,xx0,yy0 ,xpl1,ypl1); } - linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2); + linegrid.PaintLineNDC(xpl1, ypl1, xpl2, ypl2); } } } @@ -1694,7 +1692,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if (ltick == 0) { Rotate(xtick0,0,cosphi,sinphi,xx0,yy0,xpl2,ypl2); Rotate(xtick0,grid_side*gridlength ,cosphi,sinphi,xx0,yy0 ,xpl1,ypl1); - linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2); + linegrid.PaintLineNDC(xpl1, ypl1, xpl2, ypl2); } } xtick0 -= dxtick; @@ -1737,7 +1735,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if (ltick == 0) { Rotate(xtick1,0,cosphi,sinphi,xx0,yy0 ,xpl2,ypl2); Rotate(xtick1,grid_side*gridlength,cosphi,sinphi,xx0,yy0,xpl1,ypl1); - linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2); + linegrid.PaintLineNDC(xpl1, ypl1, xpl2, ypl2); } } xtick1 += dxtick; @@ -1753,7 +1751,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma // Spacing of labels if ((wmin == wmax) || (ndiv == 0)) { Error(where, "wmin (%f) == wmax (%f), or ndiv == 0", wmin, wmax); - goto L210; + return; } wlabel = wmin; dwlabel = (wmax-wmin)/Double_t(n1a); @@ -2001,31 +1999,31 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if (!optionText) { if (first > last) strncpy(chtemp, " ", 256); else strncpy(chtemp, &label[first], 255); - if (fNModLabs) ChangeLabelAttributes(k+1, nlabels, textaxis, chtemp); + if (fNModLabs) ChangeLabelAttributes(k+1, nlabels, &textaxis, chtemp); typolabel = chtemp; if (!optionTime) typolabel.ReplaceAll("-", "#minus"); if (autotoff) { UInt_t w,h; - textaxis->SetText(0.,0., typolabel.Data()); - textaxis->GetBoundingBox(w,h); + textaxis.SetText(0.,0., typolabel.Data()); + textaxis.GetBoundingBox(w,h); double scale=gPad->GetWw()*gPad->GetWNDC(); if (scale>0.0) toffset = TMath::Max(toffset,(double)w/scale); } - textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()), + textaxis.PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()), gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()), - textaxis->GetTextAngle(), - textaxis->GetTextSize(), + textaxis.GetTextAngle(), + textaxis.GetTextSize(), typolabel.Data()); - if (fNModLabs) ResetLabelAttributes(textaxis); + if (fNModLabs) ResetLabelAttributes(&textaxis); } else { strncpy(chtemp, fAxis->GetBinLabel(k+fAxis->GetFirst()), 255); - if (fNModLabs) ChangeLabelAttributes(k+fAxis->GetFirst(), fAxis->GetLabels()->GetSize()-1, textaxis, chtemp); - if (optionText == 1) textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()), + if (fNModLabs) ChangeLabelAttributes(k+fAxis->GetFirst(), fAxis->GetLabels()->GetSize()-1, &textaxis, chtemp); + if (optionText == 1) textaxis.PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()), gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()), 0, - textaxis->GetTextSize(), + textaxis.GetTextSize(), chtemp); - if (fNModLabs) ResetLabelAttributes(textaxis); + if (fNModLabs) ResetLabelAttributes(&textaxis); } } else { @@ -2042,10 +2040,10 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma } typolabel = chtemp; typolabel.ReplaceAll("-", "#minus"); - textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()), + textaxis.PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()), gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()), 0, - textaxis->GetTextSize(), + textaxis.GetTextSize(), typolabel.Data()); yy -= charheight*1.3; } @@ -2059,9 +2057,9 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if (x0 != x1) { xfactor = axis_length+0.1*charheight; yfactor = 0; } else { xfactor = y1-y0+0.1*charheight; yfactor = 0; } Rotate (xfactor,yfactor,cosphi,sinphi,x0,y0,xx,yy); - textaxis->SetTextAlign(11); + textaxis.SetTextAlign(11); if (GetLabelFont()%10 < 2) // force TLatex mode in PaintLatex - textaxis->SetTextFont((Int_t)(GetLabelFont()/10)*10+2); + textaxis.SetTextFont((Int_t)(GetLabelFont()/10)*10+2); if (fAxis && !strcmp(fAxis->GetName(),"xaxis")) { xx = xx + fXAxisExpXOffset; yy = yy + fXAxisExpYOffset; @@ -2072,10 +2070,10 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma } typolabel = label; typolabel.ReplaceAll("-", "#minus"); - textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()), + textaxis.PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()), gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()), 0, - textaxis->GetTextSize(), + textaxis.GetTextSize(), typolabel.Data()); } } @@ -2089,15 +2087,15 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma Bool_t firstintlab = kTRUE, overlap = kFALSE; if ((wmin == wmax) || (ndiv == 0)) { Error(where, "wmin (%f) == wmax (%f), or ndiv == 0", wmin, wmax); - goto L210; + return; } if (wmin <= 0) { Error(where, "negative logarithmic axis"); - goto L210; + return; } if (wmax <= 0) { Error(where, "negative logarithmic axis"); - goto L210; + return; } xmnlog = TMath::Log10(wmin); if (xmnlog > 0) xmnlog += 1.E-6; @@ -2156,7 +2154,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if (optionGrid) { Rotate(xone,0,cosphi,sinphi,x0,y0,xpl2,ypl2); Rotate(xone,grid_side*gridlength,cosphi,sinphi,x0,y0,xpl1,ypl1); - linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2); + linegrid.PaintLineNDC(xpl1, ypl1, xpl2, ypl2); } if (!drawGridOnly && !optionUnlab) { @@ -2192,7 +2190,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if ((y0 == y1) && !optionDown && !optionUp) { if (noExponent) yy += 0.33*charheight; } - if (n1a == 0)goto L210; + if (n1a == 0) return; kmod = nbinin/n1a; if (kmod == 0) kmod=1000000; if ((nbinin <= n1a) || (j == 1) || (j == nbinin) || ((nbinin > n1a) && (j%kmod == 0))) { @@ -2210,21 +2208,21 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if (fNModLabs) { if (changelablogid == 0) changelablognum = nbinin-j; changelablogid++; - ChangeLabelAttributes(changelablogid, changelablognum, textaxis, chtemp); + ChangeLabelAttributes(changelablogid, changelablognum, &textaxis, chtemp); } typolabel = chtemp; typolabel.ReplaceAll("-", "#minus"); if (autotoff) { UInt_t w,h; - textaxis->SetText(0.,0., typolabel.Data()); - textaxis->GetBoundingBox(w,h); + textaxis.SetText(0.,0., typolabel.Data()); + textaxis.GetBoundingBox(w,h); double scale=gPad->GetWw()*gPad->GetWNDC(); if (scale>0.0) toffset = TMath::Max(toffset,(double)w/scale); } - textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()), - gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()), - 0, textaxis->GetTextSize(), typolabel.Data()); - if (fNModLabs) ResetLabelAttributes(textaxis); + textaxis.PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()), + gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()), + 0, textaxis.GetTextSize(), typolabel.Data()); + if (fNModLabs) ResetLabelAttributes(&textaxis); } labelnumber++; } @@ -2298,22 +2296,22 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma else yy -= ylabel; } } - textaxis->SetTitle(chtemp); + textaxis.SetTitle(chtemp); Double_t u = gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()); Double_t v = gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()); if (firstintlab) { - textaxis->GetBoundingBox(wi, hi); wi=(UInt_t)(wi*1.3); hi=(UInt_t)(hi*1.3); + textaxis.GetBoundingBox(wi, hi); wi=(UInt_t)(wi*1.3); hi=(UInt_t)(hi*1.3); xi1 = gPad->XtoAbsPixel(u); yi1 = gPad->YtoAbsPixel(v); firstintlab = kFALSE; if (fNModLabs) { changelablogid++; - ChangeLabelAttributes(changelablogid, 0, textaxis, chtemp); + ChangeLabelAttributes(changelablogid, 0, &textaxis, chtemp); } typolabel = chtemp; typolabel.ReplaceAll("-", "#minus"); - textaxis->PaintLatex(u,v,0,textaxis->GetTextSize(),typolabel.Data()); - if (fNModLabs) ResetLabelAttributes(textaxis); + textaxis.PaintLatex(u,v,0,textaxis.GetTextSize(),typolabel.Data()); + if (fNModLabs) ResetLabelAttributes(&textaxis); } else { xi2 = gPad->XtoAbsPixel(u); yi2 = gPad->YtoAbsPixel(v); @@ -2324,15 +2322,15 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma } else { xi1 = xi2; yi1 = yi2; - textaxis->GetBoundingBox(wi, hi); wi=(UInt_t)(wi*1.3); hi=(UInt_t)(hi*1.3); + textaxis.GetBoundingBox(wi, hi); wi=(UInt_t)(wi*1.3); hi=(UInt_t)(hi*1.3); if (fNModLabs) { changelablogid++; - ChangeLabelAttributes(changelablogid, 0, textaxis, chtemp); + ChangeLabelAttributes(changelablogid, 0, &textaxis, chtemp); } typolabel = chtemp; typolabel.ReplaceAll("-", "#minus"); - textaxis->PaintLatex(u,v,0,textaxis->GetTextSize(),typolabel.Data()); - if (fNModLabs) ResetLabelAttributes(textaxis); + textaxis.PaintLatex(u,v,0,textaxis.GetTextSize(),typolabel.Data()); + if (fNModLabs) ResetLabelAttributes(&textaxis); } } } @@ -2341,7 +2339,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma if (optionGrid && nbinin <= 5 && ndiv > 100) { Rotate(xone,0,cosphi,sinphi,x0,y0,xpl2, ypl2); Rotate(xone,grid_side*gridlength,cosphi,sinphi,x0,y0, xpl1,ypl1); - linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2); + linegrid.PaintLineNDC(xpl1, ypl1, xpl2, ypl2); } } //endif ((nbinin <= idn) || } //endfor (k=2;k<10;k++) @@ -2352,7 +2350,7 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma // Draw axis title if it exists if (!drawGridOnly && strlen(GetTitle())) { - textaxis->SetTextSize (GetTitleSize()); + textaxis.SetTextSize (GetTitleSize()); charheight = GetTitleSize(); if ((GetTextFont() % 10) > 2) { charheight /= ((x1==x0) ? padw : padh); @@ -2376,35 +2374,32 @@ void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t yma else axispos = axis_length; if (TestBit(TAxis::kRotateTitle)) { if (x1 >= x0) { - if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22); - else textaxis->SetTextAlign(12); + if (TestBit(TAxis::kCenterTitle)) textaxis.SetTextAlign(22); + else textaxis.SetTextAlign(12); } else { - if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22); - else textaxis->SetTextAlign(32); + if (TestBit(TAxis::kCenterTitle)) textaxis.SetTextAlign(22); + else textaxis.SetTextAlign(32); } phil+=kPI; } else { if (x1 >= x0) { - if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22); - else textaxis->SetTextAlign(32); + if (TestBit(TAxis::kCenterTitle)) textaxis.SetTextAlign(22); + else textaxis.SetTextAlign(32); } else { - if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22); - else textaxis->SetTextAlign(12); + if (TestBit(TAxis::kCenterTitle)) textaxis.SetTextAlign(22); + else textaxis.SetTextAlign(12); } } Rotate(axispos,ylabel,cosphi,sinphi,x0,y0,xpl1,ypl1); - textaxis->SetTextColor(TitleColor); - textaxis->SetTextFont(TitleFont); - textaxis->PaintLatex(gPad->GetX1() + xpl1*(gPad->GetX2() - gPad->GetX1()), + textaxis.SetTextColor(TitleColor); + textaxis.SetTextFont(TitleFont); + textaxis.PaintLatex(gPad->GetX1() + xpl1*(gPad->GetX2() - gPad->GetX1()), gPad->GetY1() + ypl1*(gPad->GetY2() - gPad->GetY1()), phil*180/kPI, GetTitleSize(), GetTitle()); } -L210: - if (optionGrid) delete linegrid; - delete textaxis; } //////////////////////////////////////////////////////////////////////////////// @@ -2552,8 +2547,8 @@ void TGaxis::SetDecimals(Bool_t dot) void TGaxis::SetFunction(const char *funcname) { fFunctionName = funcname; - if (!funcname[0]) { - fFunction = 0; + if (!funcname || !funcname[0]) { + fFunction = nullptr; return; } fFunction = (TF1*)gROOT->GetFunction(funcname); @@ -2618,7 +2613,7 @@ void TGaxis::ChangeLabel(Int_t labNum, Double_t labAngle, Double_t labSize, // Reset the list of modified labels. if (labNum == 0) { delete fModLabs; - fModLabs = 0; + fModLabs = nullptr; fNModLabs = 0; return; } From 85968c26c1c3af187212a881c16985d20377e52c Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 14:23:29 +0200 Subject: [PATCH 067/104] Fix memory leak with TGaxis::fModLabs When custom labels for TGaxis was configured, they were never deleted. Situation is complicated, while fModLabs can point on modified labels from TAxis object. Need to be improved. --- graf2d/graf/inc/TGaxis.h | 3 +++ graf2d/graf/src/TGaxis.cxx | 54 ++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/graf2d/graf/inc/TGaxis.h b/graf2d/graf/inc/TGaxis.h index 447352fa35cd0..d3c5b8a36c06d 100644 --- a/graf2d/graf/inc/TGaxis.h +++ b/graf2d/graf/inc/TGaxis.h @@ -54,6 +54,9 @@ class TGaxis : public TLine, public TAttText { TGaxis(const TGaxis&); TGaxis& operator=(const TGaxis&); + Bool_t IsOwnedModLabs() const; + void CleanupModLabs(); + public: TGaxis(); diff --git a/graf2d/graf/src/TGaxis.cxx b/graf2d/graf/src/TGaxis.cxx index a0c767f4c5fa2..e18afacfbd261 100644 --- a/graf2d/graf/src/TGaxis.cxx +++ b/graf2d/graf/src/TGaxis.cxx @@ -813,9 +813,12 @@ TGaxis::TGaxis(const TGaxis& ax) : fTimeFormat(ax.fTimeFormat), fFunctionName(ax.fFunctionName), fFunction(ax.fFunction), - fAxis(ax.fAxis), - fModLabs(ax.fModLabs) + fAxis(ax.fAxis) { + if (ax.IsOwnedModLabs()) + fModLabs = (TList *) ax.fModLabs->Clone(); + else + fModLabs = ax.fModLabs; } //////////////////////////////////////////////////////////////////////////////// @@ -836,7 +839,6 @@ TGaxis& TGaxis::operator=(const TGaxis& ax) fTitleOffset=ax.fTitleOffset; fTitleSize=ax.fTitleSize; fNdiv=ax.fNdiv; - fModLabs=ax.fModLabs; fLabelColor=ax.fLabelColor; fLabelFont=ax.fLabelFont; fChopt=ax.fChopt; @@ -847,6 +849,7 @@ TGaxis& TGaxis::operator=(const TGaxis& ax) fFunction=ax.fFunction; fAxis=ax.fAxis; fNModLabs=ax.fNModLabs; + fModLabs = ax.IsOwnedModLabs() ? (TList *) ax.fModLabs->Clone() : ax.fModLabs; } return *this; } @@ -856,6 +859,29 @@ TGaxis& TGaxis::operator=(const TGaxis& ax) TGaxis::~TGaxis() { + CleanupModLabs(); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Returns kTRUE when fModLabs owned by TGaxis and should be cleaned up + +Bool_t TGaxis::IsOwnedModLabs() const +{ + if (!fModLabs) return kFALSE; + return !fAxis || (fAxis->GetModifiedLabels() != fModLabs); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Correctly cleanup fModLabs - delete content when owned by TGaxis + +void TGaxis::CleanupModLabs() +{ + if (IsOwnedModLabs()) { + fModLabs->Delete(); + delete fModLabs; + } + fModLabs = nullptr; + fNModLabs = 0; } //////////////////////////////////////////////////////////////////////////////// @@ -925,6 +951,8 @@ Int_t TGaxis::GetMaxDigits() void TGaxis::ImportAxisAttributes(TAxis *axis) { + // cleanup previously configured custom labels + CleanupModLabs(); fAxis = axis; SetLineColor(axis->GetAxisColor()); @@ -2604,20 +2632,24 @@ void TGaxis::SetFunction(const char *funcname) /// - If labText is not specified or is an empty string, the text label is not changed. void TGaxis::ChangeLabel(Int_t labNum, Double_t labAngle, Double_t labSize, - Int_t labAlign, Int_t labColor, Int_t labFont, - TString labText) + Int_t labAlign, Int_t labColor, Int_t labFont, + TString labText) { - fNModLabs++; - if (!fModLabs) fModLabs = new TList(); + // special situation when mod labs taken from axis - one have to reset pointer + if (fModLabs && !IsOwnedModLabs()) { + fModLabs = nullptr; + fNModLabs = 0; + } // Reset the list of modified labels. if (labNum == 0) { - delete fModLabs; - fModLabs = nullptr; - fNModLabs = 0; + CleanupModLabs(); return; } + fNModLabs++; + if (!fModLabs) fModLabs = new TList(); + TAxisModLab *ml = new TAxisModLab(); ml->SetLabNum(labNum); ml->SetAngle(labAngle); @@ -2627,7 +2659,7 @@ void TGaxis::ChangeLabel(Int_t labNum, Double_t labAngle, Double_t labSize, ml->SetFont(labFont); ml->SetText(labText); - fModLabs->Add((TObject*)ml); + fModLabs->Add(ml); } static Double_t SavedTextAngle; ///< Global variable saving the current label's text angle. Used by TGaxis::ChangeLabelAttributes. From 01003da84b4132040a4fbb9517bfae7f99a602bd Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 14:35:00 +0200 Subject: [PATCH 068/104] Use stack variables and TString in TMarker::DisplayMarkerTypes() --- graf2d/graf/src/TMarker.cxx | 88 ++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/graf2d/graf/src/TMarker.cxx b/graf2d/graf/src/TMarker.cxx index 0b9e49e12b643..32043a12faff8 100644 --- a/graf2d/graf/src/TMarker.cxx +++ b/graf2d/graf/src/TMarker.cxx @@ -102,32 +102,30 @@ void TMarker::Copy(TObject &obj) const void TMarker::DisplayMarkerTypes() { - TMarker *marker = new TMarker(); - marker->SetMarkerSize(3); - TText *text = new TText(); - text->SetTextFont(62); - text->SetTextAlign(22); - text->SetTextSize(0.1); - char atext[] = " "; + TMarker marker; + TText text; + marker.SetMarkerSize(3); + text.SetTextFont(62); + text.SetTextAlign(22); + text.SetTextSize(0.1); + TString atext; Double_t x = 0; Double_t dx = 1/16.0; for (Int_t i=1;i<16;i++) { x += dx; - snprintf(atext,7,"%d",i); - marker->SetMarkerStyle(i); - marker->DrawMarker(x,.25); - text->DrawText(x,.12,atext); - snprintf(atext,7,"%d",i+19); - marker->SetMarkerStyle(i+19); - marker->DrawMarker(x,.55); - text->DrawText(x,.42,atext); - snprintf(atext,7,"%d",i+34); - marker->SetMarkerStyle(i+34); - marker->DrawMarker(x,.85); - text->DrawText(x,.72,atext); + atext.Form("%d",i); + marker.SetMarkerStyle(i); + marker.DrawMarker(x,.25); + text.DrawText(x,.12,atext.Data()); + atext.Form("%d",i+19); + marker.SetMarkerStyle(i+19); + marker.DrawMarker(x,.55); + text.DrawText(x,.42,atext.Data()); + atext.Form("%d",i+34); + marker.SetMarkerStyle(i+34); + marker.DrawMarker(x,.85); + text.DrawText(x,.72,atext.Data()); } - delete marker; - delete text; } //////////////////////////////////////////////////////////////////////////////// @@ -135,36 +133,34 @@ void TMarker::DisplayMarkerTypes() void TMarker::DisplayMarkerLineWidths() { - TMarker *marker = new TMarker(); - marker->SetMarkerSize(3); - TText *text = new TText(); - text->SetTextFont(62); - text->SetTextAlign(22); - text->SetTextSize(0.075); - char atext[] = " "; + TMarker marker; + TText text; + marker.SetMarkerSize(3); + text.SetTextFont(62); + text.SetTextAlign(22); + text.SetTextSize(0.075); + TString atext; Double_t x = 0; Double_t dx = 1/19.0; for (Int_t i=1;i<19;i++) { x += dx; - snprintf(atext,7,"%d",i+49); - marker->SetMarkerStyle(i+49); - marker->DrawMarker(x,0.19); - text->DrawText(x,0.08,atext); - snprintf(atext,7,"%d",i+67); - marker->SetMarkerStyle(i+67); - marker->DrawMarker(x,0.42); - text->DrawText(x,0.31,atext); - snprintf(atext,7,"%d",i+85); - marker->SetMarkerStyle(i+85); - marker->DrawMarker(x,0.65); - text->DrawText(x,0.54,atext); - snprintf(atext,7,"%d",i+103); - marker->SetMarkerStyle(i+103); - marker->DrawMarker(x,0.88); - text->DrawText(x,0.77,atext); + atext.Form("%d",i+49); + marker.SetMarkerStyle(i+49); + marker.DrawMarker(x,0.19); + text.DrawText(x,0.08,atext.Data()); + atext.Form("%d",i+67); + marker.SetMarkerStyle(i+67); + marker.DrawMarker(x,0.42); + text.DrawText(x,0.31,atext.Data()); + atext.Form("%d",i+85); + marker.SetMarkerStyle(i+85); + marker.DrawMarker(x,0.65); + text.DrawText(x,0.54,atext.Data()); + atext.Form("%d",i+103); + marker.SetMarkerStyle(i+103); + marker.DrawMarker(x,0.88); + text.DrawText(x,0.77,atext.Data()); } - delete marker; - delete text; } //////////////////////////////////////////////////////////////////////////////// From fda2fd1d4f08f589af0efa543c28882e45a95e77 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 14:49:27 +0200 Subject: [PATCH 069/104] Use stack variables for TPie painting Replace `if (flag == kTRUE)` just by `if (flag)` where flag is Bool_t --- graf2d/graf/src/TPie.cxx | 105 +++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 55 deletions(-) diff --git a/graf2d/graf/src/TPie.cxx b/graf2d/graf/src/TPie.cxx index 0e0c8c01c56cf..a9aeaa9187455 100644 --- a/graf2d/graf/src/TPie.cxx +++ b/graf2d/graf/src/TPie.cxx @@ -200,7 +200,7 @@ Int_t TPie::DistancetoSlice(Int_t px, Int_t py) Double_t radX = fRadius; Double_t radY = fRadius; Double_t radXY = 1.; - if (fIs3D==kTRUE) { + if (fIs3D) { radXY = TMath::Sin(fAngle3D/180.*TMath::Pi()); radY = radXY*radX; } @@ -305,7 +305,7 @@ void TPie::DrawGhost() radXY = TMath::Sin(fAngle3D/180.*TMath::Pi()); } - for (Int_t i=0;iYtoPixel(0)-gPad->YtoPixel(fHeight); - for (Int_t pi=0;pi0) { - arc->SetFillStyle(0); - arc->SetLineColor(TColor::GetColorDark((fPieSlices[i]->GetFillColor()))); + arc.SetFillStyle(0); + arc.SetLineColor(TColor::GetColorDark((fPieSlices[i]->GetFillColor()))); } else { - arc->SetFillStyle(0); - if (optionLine==kTRUE) { - arc->SetLineColor(fPieSlices[i]->GetLineColor()); - arc->SetLineStyle(fPieSlices[i]->GetLineStyle()); - arc->SetLineWidth(fPieSlices[i]->GetLineWidth()); + arc.SetFillStyle(0); + if (optionLine) { + arc.SetLineColor(fPieSlices[i]->GetLineColor()); + arc.SetLineStyle(fPieSlices[i]->GetLineStyle()); + arc.SetLineWidth(fPieSlices[i]->GetLineWidth()); } else { - arc->SetLineWidth(1); - arc->SetLineColor(TColor::GetColorDark((fPieSlices[i]->GetFillColor()))); + arc.SetLineWidth(1); + arc.SetLineColor(TColor::GetColorDark((fPieSlices[i]->GetFillColor()))); } } // Paint the slice @@ -923,38 +923,38 @@ void TPie::Paint(Option_t *option) Double_t ax = fX+TMath::Cos(aphi)*fPieSlices[i]->GetRadiusOffset(); Double_t ay = fY+TMath::Sin(aphi)*fPieSlices[i]->GetRadiusOffset()*radXY+gPad->PixeltoY(pixelHeight-pi); - arc->PaintEllipse(ax, ay, radX, radY, fSlices[2*i], + arc.PaintEllipse(ax, ay, radX, radY, fSlices[2*i], fSlices[2*i+2], 0.); - if (optionLine==kTRUE) { - line->SetLineColor(fPieSlices[i]->GetLineColor()); - line->SetLineStyle(fPieSlices[i]->GetLineStyle()); - line->SetLineWidth(fPieSlices[i]->GetLineWidth()); - line->PaintLine(ax,ay,ax,ay); + if (optionLine) { + line.SetLineColor(fPieSlices[i]->GetLineColor()); + line.SetLineStyle(fPieSlices[i]->GetLineStyle()); + line.SetLineWidth(fPieSlices[i]->GetLineWidth()); + line.PaintLine(ax,ay,ax,ay); Double_t x0, y0; x0 = ax+radX*TMath::Cos(fSlices[2*i]/180.*TMath::Pi()); y0 = ay+radY*TMath::Sin(fSlices[2*i]/180.*TMath::Pi()); - line->PaintLine(x0,y0,x0,y0); + line.PaintLine(x0,y0,x0,y0); x0 = ax+radX*TMath::Cos(fSlices[2*i+2]/180.*TMath::Pi()); y0 = ay+radY*TMath::Sin(fSlices[2*i+2]/180.*TMath::Pi()); - line->PaintLine(x0,y0,x0,y0); + line.PaintLine(x0,y0,x0,y0); } } } // end loop for pseudo-3d effect for (Int_t i=0;iSetFillColor(fPieSlices[i]->GetFillColor()); - arc->SetFillStyle(fPieSlices[i]->GetFillStyle()); - if (optionLine==kTRUE) { - arc->SetLineColor(fPieSlices[i]->GetLineColor()); - arc->SetLineStyle(fPieSlices[i]->GetLineStyle()); - arc->SetLineWidth(fPieSlices[i]->GetLineWidth()); + arc.SetFillColor(fPieSlices[i]->GetFillColor()); + arc.SetFillStyle(fPieSlices[i]->GetFillStyle()); + if (optionLine) { + arc.SetLineColor(fPieSlices[i]->GetLineColor()); + arc.SetLineStyle(fPieSlices[i]->GetLineStyle()); + arc.SetLineWidth(fPieSlices[i]->GetLineWidth()); } else { - arc->SetLineWidth(1); - arc->SetLineColor(fPieSlices[i]->GetFillColor()); + arc.SetLineWidth(1); + arc.SetLineColor(fPieSlices[i]->GetFillColor()); } // Paint the slice @@ -962,16 +962,16 @@ void TPie::Paint(Option_t *option) Double_t ax = fX+TMath::Cos(aphi)*fPieSlices[i]->GetRadiusOffset(); Double_t ay = fY+TMath::Sin(aphi)*fPieSlices[i]->GetRadiusOffset()*radXY; - arc->PaintEllipse(ax, ay, radX, radY, fSlices[2*i], + arc.PaintEllipse(ax, ay, radX, radY, fSlices[2*i], fSlices[2*i+2], 0.); } // end loop to draw the slices // Set the font - textlabel->SetTextFont(GetTextFont()); - textlabel->SetTextSize(GetTextSize()); - textlabel->SetTextColor(GetTextColor()); + textlabel.SetTextFont(GetTextFont()); + textlabel.SetTextSize(GetTextSize()); + textlabel.SetTextColor(GetTextColor()); // Loop to place the labels. for (Int_t i=0;iGetValue()/fSum)); tmptxt.ReplaceAll("%perc",Form(Form("%s %s",fPercentFormat.Data(),"%s"),(fPieSlices[i]->GetValue()/fSum)*100,"%")); - textlabel->SetTitle(tmptxt.Data()); - Double_t h = textlabel->GetYsize(); - Double_t w = textlabel->GetXsize(); + textlabel.SetTitle(tmptxt.Data()); + Double_t h = textlabel.GetYsize(); + Double_t w = textlabel.GetXsize(); Float_t lx = fX+(fRadius+fPieSlices[i]->GetRadiusOffset()+label_off)*TMath::Cos(aphi); Float_t ly = fY+(fRadius+fPieSlices[i]->GetRadiusOffset()+label_off)*TMath::Sin(aphi)*radXY; @@ -1037,22 +1037,17 @@ void TPie::Paint(Option_t *option) if (rphi < 0 && fIs3D && label_off>=0.) ly -= fHeight; - if (optionSameColor) textlabel->SetTextColor((fPieSlices[i]->GetFillColor())); - textlabel->PaintLatex(lx,ly, - lblang*180/TMath::Pi()+GetTextAngle(), - GetTextSize(), tmptxt.Data()); + if (optionSameColor) textlabel.SetTextColor((fPieSlices[i]->GetFillColor())); + textlabel.PaintLatex(lx,ly, + lblang*180/TMath::Pi()+GetTextAngle(), + GetTextSize(), tmptxt.Data()); } - delete arc; - delete line; - delete textlabel; - if (optionSame) return; // Draw title - TPaveText *title = 0; - TObject *obj; - if ((obj = gPad->GetListOfPrimitives()->FindObject("title"))) { + TPaveText *title = nullptr; + if (auto obj = gPad->GetListOfPrimitives()->FindObject("title")) { title = dynamic_cast(obj); } From 6a9e6e5987a5a79f43fc3f0cf0c1772df90442f7 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 14:50:28 +0200 Subject: [PATCH 070/104] Use stack variables for TPave painting --- graf2d/graf/src/TPaveStats.cxx | 30 +++++++++++++----------------- graf2d/graf/src/TPaveText.cxx | 15 +++++++-------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/graf2d/graf/src/TPaveStats.cxx b/graf2d/graf/src/TPaveStats.cxx index bf7db025dc2e1..79c32d0041f87 100644 --- a/graf2d/graf/src/TPaveStats.cxx +++ b/graf2d/graf/src/TPaveStats.cxx @@ -344,8 +344,6 @@ void TPaveStats::Paint(Option_t *option) Float_t margin = fMargin*dx; Double_t yspace = dy/Double_t(nlines); Double_t textsave = textsize; - TObject *line; - TLatex *latex, *latex_tok; TIter next(fLines); Double_t longest = 0, titlelength = 0; Double_t w, wtok[2]; @@ -354,9 +352,9 @@ void TPaveStats::Paint(Option_t *option) textsize = 0.92*yspace/(y2 - y1); titlesize = textsize; wtok[0] = wtok[1] = 0; - while ((line = (TObject*) next())) { + while (auto line = (TObject*) next()) { if (line->IsA() == TLatex::Class()) { - latex = (TLatex*)line; + TLatex *latex = (TLatex*)line; Int_t nchs = strlen(latex->GetTitle()); sl = new char[nchs+1]; strlcpy(sl, latex->GetTitle(),nchs+1); @@ -364,16 +362,15 @@ void TPaveStats::Paint(Option_t *option) st = strtok(sl, "="); Int_t itok = 0; while (( st != 0 ) && (itok < 2)) { - latex_tok = new TLatex(0.,0.,st); + TLatex latex_tok(0.,0.,st); Style_t tfont = latex->GetTextFont(); if (tfont == 0) tfont = GetTextFont(); - latex_tok->SetTextFont(tfont); - latex_tok->SetTextSize(textsize); - w = latex_tok->GetXsize(); + latex_tok.SetTextFont(tfont); + latex_tok.SetTextSize(textsize); + w = latex_tok.GetXsize(); if (w > wtok[itok]) wtok[itok] = w; st = strtok(0, "="); ++itok; - delete latex_tok; } } else if (strpbrk(sl, "|") !=0) { } else { @@ -401,9 +398,9 @@ void TPaveStats::Paint(Option_t *option) // Iterate over all lines // Copy pavetext attributes to line attributes if line attributes not set next.Reset(); - while ((line = (TObject*) next())) { + while (auto line = (TObject*) next()) { if (line->IsA() == TLatex::Class()) { - latex = (TLatex*)line; + TLatex *latex = (TLatex*)line; ytext -= yspace; Double_t xl = latex->GetX(); Double_t yl = latex->GetY(); @@ -491,12 +488,11 @@ void TPaveStats::Paint(Option_t *option) x2 = x2ref - 0.25*dx; y1 = y2ref - 0.02*dy; y2 = y2ref + 0.02*dy; - TPaveLabel *title = new TPaveLabel(x1,y1,x2,y2,fLabel.Data(),GetDrawOption()); - title->SetFillColor(GetFillColor()); - title->SetTextColor(GetTextColor()); - title->SetTextFont(GetTextFont()); - title->Paint(); - delete title; + TPaveLabel title(x1,y1,x2,y2,fLabel.Data(),GetDrawOption()); + title.SetFillColor(GetFillColor()); + title.SetTextColor(GetTextColor()); + title.SetTextFont(GetTextFont()); + title.Paint(); } } diff --git a/graf2d/graf/src/TPaveText.cxx b/graf2d/graf/src/TPaveText.cxx index 5ed876879253c..a86472b7ab972 100644 --- a/graf2d/graf/src/TPaveText.cxx +++ b/graf2d/graf/src/TPaveText.cxx @@ -118,7 +118,7 @@ TPaveText::~TPaveText() if (!TestBit(kNotDeleted)) return; if (fLines) fLines->Delete(); delete fLines; - fLines = 0; + fLines = nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -131,7 +131,7 @@ TPaveText::TPaveText(const TPaveText &pavetext) : TPave(), TAttText() p->Streamer(b); b.SetReadMode(); b.SetBufferOffset(0); - fLines = 0; + fLines = nullptr; Streamer(b); } @@ -568,12 +568,11 @@ void TPaveText::PaintPrimitives(Int_t mode) x2 = fX2 - 0.25*dx; y1 = fY2 - 0.02*dy; y2 = fY2 + 0.02*dy; - TPaveLabel *title = new TPaveLabel(x1,y1,x2,y2,fLabel.Data(),GetDrawOption()); - title->SetFillColor(GetFillColor()); - title->SetTextColor(GetTextColor()); - title->SetTextFont(GetTextFont()); - title->Paint(); - delete title; + TPaveLabel title(x1,y1,x2,y2,fLabel.Data(),GetDrawOption()); + title.SetFillColor(GetFillColor()); + title.SetTextColor(GetTextColor()); + title.SetTextFont(GetTextFont()); + title.Paint(); } } From 212c0ddc746bb4d54fa7233a125578a2a63d939d Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Tue, 28 Jun 2022 15:28:21 +0200 Subject: [PATCH 071/104] Set owner flag for TGaxis::fModLabs list of labels It is the only workaround to support I/O of TGaxis. If TGaxis was configured from histogram axis and stored, it may store `fModLabs` list from TAxis. After reading back such object from the file one has no information about ownership. Therefore now only lists with configured ownership are deleted - making no crash with old ROOT files. --- graf2d/graf/src/TGaxis.cxx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/graf2d/graf/src/TGaxis.cxx b/graf2d/graf/src/TGaxis.cxx index e18afacfbd261..c5c9d7394675f 100644 --- a/graf2d/graf/src/TGaxis.cxx +++ b/graf2d/graf/src/TGaxis.cxx @@ -868,7 +868,10 @@ TGaxis::~TGaxis() Bool_t TGaxis::IsOwnedModLabs() const { if (!fModLabs) return kFALSE; - return !fAxis || (fAxis->GetModifiedLabels() != fModLabs); + if (fAxis && (fAxis->GetModifiedLabels() == fModLabs)) return kFALSE; + // TList created by TGaxis configured with owner flag + // If TGaxis object from old ROOT file will be read, memory will be leaked + return fModLabs->IsOwner(); } //////////////////////////////////////////////////////////////////////////////// @@ -2648,7 +2651,10 @@ void TGaxis::ChangeLabel(Int_t labNum, Double_t labAngle, Double_t labSize, } fNModLabs++; - if (!fModLabs) fModLabs = new TList(); + if (!fModLabs) { + fModLabs = new TList(); + fModLabs->SetOwner(kTRUE); + } TAxisModLab *ml = new TAxisModLab(); ml->SetLabNum(labNum); @@ -2682,15 +2688,13 @@ void TGaxis::ChangeLabelAttributes(Int_t i, Int_t nlabels, TLatex* t, char* c) if (!fModLabs) return; TIter next(fModLabs); - TAxisModLab *ml; - Int_t labNum; - while ( (ml = (TAxisModLab*)next()) ) { + while (auto ml = (TAxisModLab*)next()) { SavedTextAngle = t->GetTextAngle(); SavedTextSize = t->GetTextSize(); SavedTextAlign = t->GetTextAlign(); SavedTextColor = t->GetTextColor(); SavedTextFont = t->GetTextFont(); - labNum = ml->GetLabNum(); + Int_t labNum = ml->GetLabNum(); if (labNum < 0) { if (TestBit(TAxis::kMoreLogLabels)) { Error("ChangeLabelAttributes", "reverse numbering in ChangeLabel doesn't work when more log labels are requested"); From a78a57135e5c7b56e8416c218123421401fcfff5 Mon Sep 17 00:00:00 2001 From: Enrico Guiraud Date: Tue, 28 Jun 2022 20:59:45 +0200 Subject: [PATCH 072/104] [DF] Declare single-argument ctor explicit As per C++ core guidelines. --- tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx | 2 +- tree/dataframe/inc/ROOT/RDF/RDefinePerSample.hxx | 4 ++-- tree/dataframe/test/dataframe_utils.cxx | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx b/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx index c219c5c5d93b3..7c309ad694cdf 100644 --- a/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RColumnRegister.hxx @@ -68,7 +68,7 @@ public: RColumnRegister(RColumnRegister &&) = default; RColumnRegister &operator=(const RColumnRegister &) = default; - RColumnRegister(std::shared_ptr lm) + explicit RColumnRegister(std::shared_ptr lm) : fLoopManager(lm), fDefines(std::make_shared()), fAliases(std::make_shared>()), fVariations(std::make_shared()), fColumnNames(std::make_shared()) diff --git a/tree/dataframe/inc/ROOT/RDF/RDefinePerSample.hxx b/tree/dataframe/inc/ROOT/RDF/RDefinePerSample.hxx index 188ff7a989e42..6219bc5666614 100644 --- a/tree/dataframe/inc/ROOT/RDF/RDefinePerSample.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RDefinePerSample.hxx @@ -39,8 +39,8 @@ class R__CLING_PTRCHECK(off) RDefinePerSample final : public RDefineBase { public: RDefinePerSample(std::string_view name, std::string_view type, F expression, RLoopManager &lm) - : RDefineBase(name, type, /*colRegister*/ {nullptr}, lm, /*columnNames*/ {}), fExpression(std::move(expression)), - fLastResults(lm.GetNSlots() * RDFInternal::CacheLineStep()) + : RDefineBase(name, type, RDFInternal::RColumnRegister{nullptr}, lm, /*columnNames*/ {}), + fExpression(std::move(expression)), fLastResults(lm.GetNSlots() * RDFInternal::CacheLineStep()) { } diff --git a/tree/dataframe/test/dataframe_utils.cxx b/tree/dataframe/test/dataframe_utils.cxx index 3fecc29e2e2de..b3a551d563255 100644 --- a/tree/dataframe/test/dataframe_utils.cxx +++ b/tree/dataframe/test/dataframe_utils.cxx @@ -171,8 +171,8 @@ TEST(RDataFrameUtils, FindUnknownColumnsNestedNames) DummyStruct s{1, 2}; t.Branch("s", &s, "a/I:b/I"); - auto unknownCols = - RDFInt::FindUnknownColumns({"s.a", "s.b", "s", "s.", ".s", "_asd_"}, RDFInt::GetBranchNames(t), {nullptr}, {}); + auto unknownCols = RDFInt::FindUnknownColumns({"s.a", "s.b", "s", "s.", ".s", "_asd_"}, RDFInt::GetBranchNames(t), + RDFInt::RColumnRegister{nullptr}, {}); const auto trueUnknownCols = std::vector({"s", "s.", ".s", "_asd_"}); EXPECT_EQ(unknownCols, trueUnknownCols); } @@ -199,7 +199,8 @@ TEST(RDataFrameUtils, FindUnknownColumnsFriendTrees) t1.AddFriend(&t2); t1.AddFriend(&t4); - auto ncols = RDFInt::FindUnknownColumns({"c2", "c3", "c4"}, RDFInt::GetBranchNames(t1), {nullptr}, {}); + auto ncols = + RDFInt::FindUnknownColumns({"c2", "c3", "c4"}, RDFInt::GetBranchNames(t1), RDFInt::RColumnRegister{nullptr}, {}); EXPECT_EQ(ncols.size(), 0u) << "Cannot find column in friend trees."; } From d37a2ae2c160e162dbe58191c8fd5e2bc119fd8c Mon Sep 17 00:00:00 2001 From: Enrico Guiraud Date: Tue, 28 Jun 2022 19:11:28 +0200 Subject: [PATCH 073/104] [DF] Fix iteration over multimap Before this patch, we were iterating until the end of the map rather than until the end of the equal_range (this was not a problem in practice because program logic guaranteed that we would find what we were looking for and break out of the loop early). --- tree/dataframe/src/RDFColumnRegister.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tree/dataframe/src/RDFColumnRegister.cxx b/tree/dataframe/src/RDFColumnRegister.cxx index 3e7bf7f49b72b..38fa086431d16 100644 --- a/tree/dataframe/src/RDFColumnRegister.cxx +++ b/tree/dataframe/src/RDFColumnRegister.cxx @@ -117,9 +117,9 @@ RVariationBase &RColumnRegister::FindVariation(const std::string &colName, const auto range = fVariations->equal_range(colName); assert(range.first != fVariations->end() && "Could not find the variation you asked for. This should never happen."); auto it = range.first; - while (it != fVariations->end() && !IsStrInVec(variationName, it->second->GetVariationNames())) + while (it != range.second && !IsStrInVec(variationName, it->second->GetVariationNames())) ++it; - assert(it != fVariations->end() && "Could not find the variation you asked for. This should never happen."); + assert(it != range.second && "Could not find the variation you asked for. This should never happen."); return *it->second; } From fc4e3e8f340ff4609f7dcaef0de12756e7ade327 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 08:51:19 +0200 Subject: [PATCH 074/104] [gpad] use TString instead plain char arrays in TCanvas methods --- graf2d/gpad/src/TCanvas.cxx | 66 ++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/graf2d/gpad/src/TCanvas.cxx b/graf2d/gpad/src/TCanvas.cxx index 3061701d25c1a..5695f9f007f06 100644 --- a/graf2d/gpad/src/TCanvas.cxx +++ b/graf2d/gpad/src/TCanvas.cxx @@ -160,18 +160,18 @@ TCanvas::TCanvas(Bool_t build) : TPad(), fDoubleBuffer(0) Constructor(); } else { const char *defcanvas = gROOT->GetDefCanvasName(); - char *cdef; + TString cdef; auto lc = (TList*)gROOT->GetListOfCanvases(); if (lc->FindObject(defcanvas)) { - Int_t n = lc->GetSize()+1; - while (lc->FindObject(Form("%s_n%d",defcanvas,n))) n++; - cdef = StrDup(Form("%s_n%d",defcanvas,n)); + Int_t n = lc->GetSize() + 1; + do { + cdef.Form("%s_n%d",defcanvas,n++); + } while (lc->FindObject(cdef.Data())); } else { - cdef = StrDup(Form("%s",defcanvas)); + cdef = defcanvas; } - Constructor(cdef, cdef, 1); - delete [] cdef; + Constructor(cdef.Data(), cdef.Data(), 1); } } @@ -1504,22 +1504,20 @@ void TCanvas::ls(Option_t *option) const TCanvas *TCanvas::MakeDefCanvas() { const char *defcanvas = gROOT->GetDefCanvasName(); - char *cdef; + TString cdef; auto lc = (TList*)gROOT->GetListOfCanvases(); if (lc->FindObject(defcanvas)) { Int_t n = lc->GetSize() + 1; - cdef = new char[strlen(defcanvas)+15]; do { - strlcpy(cdef,Form("%s_n%d", defcanvas, n++),strlen(defcanvas)+15); - } while (lc->FindObject(cdef)); + cdef.Form("%s_n%d", defcanvas, n++); + } while (lc->FindObject(cdef.Data())); } else - cdef = StrDup(Form("%s",defcanvas)); + cdef = defcanvas; - TCanvas *c = new TCanvas(cdef, cdef, 1); + TCanvas *c = new TCanvas(cdef.Data(), cdef.Data(), 1); - ::Info("TCanvas::MakeDefCanvas"," created default TCanvas with name %s",cdef); - delete [] cdef; + ::Info("TCanvas::MakeDefCanvas"," created default TCanvas with name %s",cdef.Data()); return c; } @@ -1834,32 +1832,25 @@ void TCanvas::SaveSource(const char *filename, Option_t *option) char quote = '"'; std::ofstream out; - Int_t lenfile = strlen(filename); - char * fname; - char lcname[10]; + TString fname; const char *cname = GetName(); Bool_t invalid = kFALSE; // if filename is given, open this file, otherwise create a file // with a name equal to the canvasname.C - if (lenfile) { - fname = (char*)filename; - out.open(fname, std::ios::out); + if (filename && (strlen(filename) > 0)) { + fname = filename; } else { - Int_t nch = strlen(cname); - if (nch < 10) { - strlcpy(lcname,cname,10); - for (Int_t k=1;k<=nch;k++) {if (lcname[nch-k] == ' ') lcname[nch-k] = 0;} - if (lcname[0] == 0) {invalid = kTRUE; strlcpy(lcname,"c1",10); nch = 2;} - cname = lcname; + fname = cname; + fname = fname.Strip(TString::kBoth); + if (fname.IsNull()) { + invalid = kTRUE; + fname = "c1"; } - fname = new char[nch+3]; - strlcpy(fname,cname,nch+3); - strncat(fname,".C",3); - out.open(fname, std::ios::out); - } - if (!out.good ()) { - Error("SaveSource", "Cannot open file: %s",fname); - if (!lenfile) delete [] fname; + fname.Append(".C"); + } + out.open(fname.Data(), std::ios::out); + if (!out.good()) { + Error("SaveSource", "Cannot open file: %s", fname.Data()); return; } @@ -1887,7 +1878,7 @@ void TCanvas::SaveSource(const char *filename, Option_t *option) topx = 1; topy = 1; } - TString mname(fname); + TString mname = fname; out << R"CODE(#ifdef __CLING__ #pragma cling optimize(0) #endif @@ -1960,14 +1951,13 @@ void TCanvas::SaveSource(const char *filename, Option_t *option) out <<"}"<ResetBit(TClass::kClassSaved); } - if (!lenfile) delete [] fname; } //////////////////////////////////////////////////////////////////////////////// From 9545522f2bc786f9226cff2b36f34af45afa4eb4 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 09:00:24 +0200 Subject: [PATCH 075/104] use std::vector for collide grid in TPad Simplifies memory management --- graf2d/gpad/inc/TPad.h | 3 ++- graf2d/gpad/src/TPad.cxx | 31 +++++++++---------------------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/graf2d/gpad/inc/TPad.h b/graf2d/gpad/inc/TPad.h index 4d043addf9a1e..b6ab71cbd3bdd 100644 --- a/graf2d/gpad/inc/TPad.h +++ b/graf2d/gpad/inc/TPad.h @@ -14,6 +14,7 @@ #include "TVirtualPad.h" #include "TAttBBox2D.h" +#include class TVirtualViewer3D; class TVirtualPadPainter; @@ -111,7 +112,7 @@ class TPad : public TVirtualPad, public TAttBBox2D { static Int_t fgMaxPickDistance; ///< Maximum Pick Distance Int_t fNumPaletteColor; ///< Number of objects with an automatic color Int_t fNextPaletteColor; ///< Next automatic color - Bool_t *fCollideGrid; /// fCollideGrid;///GetWw())/cellSize; @@ -3042,29 +3036,22 @@ void TPad::FillCollideGrid(TObject *oi) if (fCGnx != CGnx || fCGny != CGny) { fCGnx = CGnx; fCGny = CGny; - delete [] fCollideGrid; - fCollideGrid = nullptr; } } // Initialise the collide grid - if (!fCollideGrid) { - fCollideGrid = new Bool_t [fCGnx*fCGny]; - for (int i = 0; iGetSize(); - TObject *o; for (int i=0; iAt(i); + TObject *o = (TObject *) l->At(i); if (o!=oi) { if (o->InheritsFrom(TFrame::Class())) { FillCollideGridTFrame(o); continue;} if (o->InheritsFrom(TBox::Class())) { FillCollideGridTBox(o); continue;} From 7d9f1939ad030ae719f1ce68fa07ba4476c021ff Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 09:09:49 +0200 Subject: [PATCH 076/104] Use vector and TString in TPad methods Avoid direct dynamic allocation of plain C arrays --- graf2d/gpad/src/TPad.cxx | 58 +++++++++++++--------------------------- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/graf2d/gpad/src/TPad.cxx b/graf2d/gpad/src/TPad.cxx index 6685b8fdd6621..c52a00f20fc96 100644 --- a/graf2d/gpad/src/TPad.cxx +++ b/graf2d/gpad/src/TPad.cxx @@ -863,8 +863,7 @@ Int_t TPad::ClipPolygon(Int_t n, Double_t *x, Double_t *y, Int_t nn, Double_t *x Int_t nc, nc2; Double_t x1, y1, x2, y2, slope; // Segment to be clipped - Double_t *xc2 = new Double_t[nn]; - Double_t *yc2 = new Double_t[nn]; + std::vector xc2(nn), yc2(nn); // Clip against the left boundary x1 = x[n-1]; y1 = y[n-1]; @@ -970,9 +969,6 @@ Int_t TPad::ClipPolygon(Int_t n, Double_t *x, Double_t *y, Int_t nn, Double_t *x } } - delete [] xc2; - delete [] yc2; - if (nc < 3) nc =0; return nc; } @@ -1165,7 +1161,6 @@ void TPad::Divide(Int_t nx, Int_t ny, Float_t xmargin, Float_t ymargin, Int_t co { if (!IsEditable()) return; - if (gThreadXAR) { void *arr[7]; arr[1] = this; arr[2] = (void*)&nx;arr[3] = (void*)& ny; @@ -1177,14 +1172,10 @@ void TPad::Divide(Int_t nx, Int_t ny, Float_t xmargin, Float_t ymargin, Int_t co cd(); if (nx <= 0) nx = 1; if (ny <= 0) ny = 1; - Int_t ix,iy; - Double_t x1,y1,x2,y2; - Double_t dx,dy; + Int_t ix, iy; + Double_t x1, y1, x2, y2, dx, dy; TPad *pad; - Int_t nchname = strlen(GetName())+6; - Int_t nchtitle = strlen(GetTitle())+6; - char *name = new char [nchname]; - char *title = new char [nchtitle]; + TString name, title; Int_t n = 0; if (color == 0) color = GetFillColor(); if (xmargin > 0 && ymargin > 0) { @@ -1201,8 +1192,8 @@ void TPad::Divide(Int_t nx, Int_t ny, Float_t xmargin, Float_t ymargin, Int_t co x2 = x1 +dx -2*xmargin; if (x1 > x2) continue; n++; - snprintf(name,nchname,"%s_%d",GetName(),n); - pad = new TPad(name,name,x1,y1,x2,y2,color); + name.Form("%s_%d", GetName(), n); + pad = new TPad(name.Data(), name.Data(), x1, y1, x2, y2, color); pad->SetNumber(n); pad->Draw(); } @@ -1235,9 +1226,9 @@ void TPad::Divide(Int_t nx, Int_t ny, Float_t xmargin, Float_t ymargin, Int_t co y1 = y2 - dy; if (j == 0) y2 = 1-yt; if (j == ny-1) y1 = 0; - snprintf(name,nchname,"%s_%d",GetName(),number); - snprintf(title,nchtitle,"%s_%d",GetTitle(),number); - pad = new TPad(name,title,x1,y1,x2,y2); + name.Form("%s_%d", GetName(), number); + title.Form("%s_%d", GetTitle(), number); + pad = new TPad(name.Data(), title.Data(), x1, y1, x2, y2); pad->SetNumber(number); pad->SetBorderMode(0); if (i == 0) pad->SetLeftMargin(xl*nx); @@ -1250,8 +1241,6 @@ void TPad::Divide(Int_t nx, Int_t ny, Float_t xmargin, Float_t ymargin, Int_t co } } } - delete [] name; - delete [] title; Modified(); if (padsav) padsav->cd(); } @@ -1594,7 +1583,7 @@ void TPad::DrawCrosshair() TH1F *TPad::DrawFrame(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, const char *title) { - if (!IsEditable()) return 0; + if (!IsEditable()) return nullptr; TPad *padsav = (TPad*)gPad; if (this != padsav) { Warning("DrawFrame","Must be called for the current pad only"); @@ -1612,13 +1601,12 @@ TH1F *TPad::DrawFrame(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax Double_t xminl = TMath::Log(xmin); Double_t xmaxl = TMath::Log(xmax); Double_t dx = (xmaxl-xminl)/nbins; - Double_t *xbins = new Double_t[nbins+1]; + std::vector xbins(nbins+1); xbins[0] = xmin; for (Int_t i=1;i<=nbins;i++) { xbins[i] = TMath::Exp(xminl+i*dx); } - hframe = new TH1F("hframe",title,nbins,xbins); - delete [] xbins; + hframe = new TH1F("hframe",title,nbins,xbins.data()); } else { hframe = new TH1F("hframe",title,nbins,xmin,xmax); } @@ -3912,15 +3900,12 @@ void TPad::PaintFillArea(Int_t nn, Double_t *xx, Double_t *yy, Option_t *) void TPad::PaintFillAreaNDC(Int_t n, Double_t *x, Double_t *y, Option_t *option) { - auto xw = new Double_t[n]; - auto yw = new Double_t[n]; + std::vector xw(n), yw(n); for (int i=0; iDrawPolyLineNDC(n, x, y); if (gVirtualPS) { - Double_t *xw = new Double_t[n]; - Double_t *yw = new Double_t[n]; + std::vector xw(n), yw(n); for (Int_t i=0; iDrawPS(n, xw, yw); - delete [] xw; - delete [] yw; + gVirtualPS->DrawPS(n, xw.data(), yw.data()); } Modified(); } @@ -4646,13 +4628,11 @@ void TPad::Pop() if (this == fMother->GetListOfPrimitives()->Last()) return; TListIter next(fMother->GetListOfPrimitives()); - TObject *obj; - while ((obj = next())) + while (auto obj = next()) if (obj == this) { - char *opt = StrDup(next.GetOption()); + TString opt = next.GetOption(); fMother->GetListOfPrimitives()->Remove(this); - fMother->GetListOfPrimitives()->AddLast(this, opt); - delete [] opt; + fMother->GetListOfPrimitives()->AddLast(this, opt.Data()); return; } } From c6fe4f5f7053638a951fd96e8758738cedbc5aac Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 09:30:30 +0200 Subject: [PATCH 077/104] Use nullptr in TPad.cxx --- graf2d/gpad/src/TPad.cxx | 91 ++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 51 deletions(-) diff --git a/graf2d/gpad/src/TPad.cxx b/graf2d/gpad/src/TPad.cxx index c52a00f20fc96..6d57c9db2f2a7 100644 --- a/graf2d/gpad/src/TPad.cxx +++ b/graf2d/gpad/src/TPad.cxx @@ -442,7 +442,7 @@ TPad::~TPad() /// to develop more powerful interactive applications exploiting the C++ /// interpreter as a development engine. -void TPad::AddExec(const char *name, const char*command) +void TPad::AddExec(const char *name, const char *command) { if (!fExecs) fExecs = new TList; TExec *ex = new TExec(name,command); @@ -458,10 +458,8 @@ void TPad::AutoExec() if (!fExecs) fExecs = new TList; TIter next(fExecs); - TExec *exec; - while ((exec = (TExec*)next())) { + while (auto exec = (TExec*)next()) exec->Exec(); - } } //////////////////////////////////////////////////////////////////////////////// @@ -502,14 +500,13 @@ void TPad::Browse(TBrowser *b) TLegend *TPad::BuildLegend(Double_t x1, Double_t y1, Double_t x2, Double_t y2, const char* title, Option_t *option) { - TList *lop=GetListOfPrimitives(); - if (!lop) return 0; - TLegend *leg=0; + TList *lop = GetListOfPrimitives(); + if (!lop) return nullptr; + TLegend *leg = nullptr; TIter next(lop); TString mes; - TObject *o=0; TString opt(""); - while( (o=next()) ) { + while(auto o = next()) { if ((o->InheritsFrom(TAttLine::Class()) || o->InheritsFrom(TAttMarker::Class()) || o->InheritsFrom(TAttFill::Class())) && ( !(o->InheritsFrom(TFrame::Class())) && !(o->InheritsFrom(TPave::Class())) )) { @@ -562,9 +559,8 @@ TLegend *TPad::BuildLegend(Double_t x1, Double_t y1, Double_t x2, Double_t y2, opt = ""; } if (leg) { - TVirtualPad *gpadsave; - gpadsave = gPad; - this->cd(); + TVirtualPad *gpadsave = gPad; + cd(); leg->Draw(); gpadsave->cd(); } else { @@ -609,10 +605,9 @@ TVirtualPad *TPad::cd(Int_t subpadnumber) return gPad; } - TObject *obj; if (!fPrimitives) fPrimitives = new TList; TIter next(fPrimitives); - while ((obj = next())) { + while (auto obj = next()) { if (obj->InheritsFrom(TPad::Class())) { Int_t n = ((TPad*)obj)->GetNumber(); if (n == subpadnumber) { @@ -620,7 +615,7 @@ TVirtualPad *TPad::cd(Int_t subpadnumber) } } } - return 0; + return nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -740,7 +735,7 @@ Int_t TPad::Clip(Float_t *x, Float_t *y, Float_t xclipl, Float_t yclipb, Float_t Int_t TPad::Clip(Double_t *x, Double_t *y, Double_t xclipl, Double_t yclipb, Double_t xclipr, Double_t yclipt) { - const Double_t kP=10000; + const Double_t kP = 10000; Int_t clip = 0; for (Int_t i=0;i<2;i++) { @@ -1052,10 +1047,9 @@ void TPad::CopyPixmap() void TPad::CopyPixmaps() { - TObject *obj; if (!fPrimitives) fPrimitives = new TList; TIter next(GetListOfPrimitives()); - while ((obj = next())) { + while (auto obj = next()) { if (obj->InheritsFrom(TPad::Class())) { ((TPad*)obj)->CopyPixmap(); ((TPad*)obj)->CopyPixmaps(); @@ -2603,9 +2597,8 @@ TObject *TPad::FindObject(const char *name) const if (!fPrimitives) return nullptr; TObject *found = fPrimitives->FindObject(name); if (found) return found; - TObject *cur; TIter next(GetListOfPrimitives()); - while ((cur = next())) { + while (auto cur = next()) { if (cur->InheritsFrom(TPad::Class())) { found = ((TPad*)cur)->FindObject(name); if (found) return found; @@ -2624,9 +2617,8 @@ TObject *TPad::FindObject(const TObject *obj) const if (!fPrimitives) return nullptr; TObject *found = fPrimitives->FindObject(obj); if (found) return found; - TObject *cur; TIter next(GetListOfPrimitives()); - while ((cur = next())) { + while (auto cur = next()) { if (cur->InheritsFrom(TPad::Class())) { found = ((TPad*)cur)->FindObject(obj); if (found) return found; @@ -3438,11 +3430,10 @@ void TPad::Paint(Option_t * /*option*/) PaintDate(); TObjOptLink *lnk = (TObjOptLink*)GetListOfPrimitives()->FirstLink(); - TObject *obj; Bool_t began3DScene = kFALSE; while (lnk) { - obj = lnk->GetObject(); + TObject *obj = lnk->GetObject(); // Create a pad 3D viewer if none exists and we encounter a 3D shape if (!fViewer3D && obj->InheritsFrom(TAtt3D::Class())) { @@ -3650,7 +3641,7 @@ void TPad::PaintModified() Modified(kFALSE); } TList *pList = GetListOfPrimitives(); - TObjOptLink *lnk = 0; + TObjOptLink *lnk = nullptr; if (pList) lnk = (TObjOptLink*)pList->FirstLink(); TObject *obj; while (lnk) { @@ -3667,7 +3658,7 @@ void TPad::PaintModified() TPad *padsav = (TPad*)gPad; TVirtualPS *saveps = gVirtualPS; if (gVirtualPS) { - if (gVirtualPS->TestBit(kPrintingPS)) gVirtualPS = 0; + if (gVirtualPS->TestBit(kPrintingPS)) gVirtualPS = nullptr; } fPadPaint = 1; cd(); @@ -3681,14 +3672,13 @@ void TPad::PaintModified() PaintDate(); TList *pList = GetListOfPrimitives(); - TObjOptLink *lnk = 0; + TObjOptLink *lnk = nullptr; if (pList) lnk = (TObjOptLink*)pList->FirstLink(); - TObject *obj; Bool_t began3DScene = kFALSE; while (lnk) { - obj = lnk->GetObject(); + TObject *obj = lnk->GetObject(); if (obj->InheritsFrom(TPad::Class())) { ((TPad*)obj)->PaintModified(); } else if (IsModified() || IsTransparent()) { @@ -4506,24 +4496,24 @@ TPad *TPad::Pick(Int_t px, Int_t py, TObjLink *&pickobj) //the two following statements are necessary under NT (multithreaded) //when a TCanvas object is being created and a thread calling TPad::Pick //before the TPad constructor has completed in the other thread - if (gPad == 0) return 0; //Andy Haas - if (GetListOfPrimitives() == 0) return 0; //Andy Haas + if (!gPad) return nullptr; //Andy Haas + if (!GetListOfPrimitives()) return nullptr; //Andy Haas Int_t dist; // Search if point is in pad itself Double_t x = AbsPixeltoX(px); Double_t y = AbsPixeltoY(py); if (this != gPad->GetCanvas()) { - if (!((x >= fX1 && x <= fX2) && (y >= fY1 && y <= fY2))) return 0; + if (!((x >= fX1 && x <= fX2) && (y >= fY1 && y <= fY2))) return nullptr; } // search for a primitive in this pad or its sub-pads - static TObjOptLink dummyLink(0,""); //place holder for when no link available + static TObjOptLink dummyLink(nullptr,""); //place holder for when no link available TPad *padsav = (TPad*)gPad; gPad = this; // since no drawing will be done, don't use cd() for efficiency reasons - TPad *pick = 0; + TPad *pick = nullptr; TPad *picked = this; - pickobj = 0; + pickobj = nullptr; if (DistancetoPrimitive(px,py) < fgMaxPickDistance) { dummyLink.SetObject(this); pickobj = &dummyLink; @@ -4601,14 +4591,14 @@ TPad *TPad::Pick(Int_t px, Int_t py, TObjLink *&pickobj) if (picked->InheritsFrom(TButton::Class())) { TButton *button = (TButton*)picked; - if (!button->IsEditable()) pickobj = 0; + if (!button->IsEditable()) pickobj = nullptr; } if (TestBit(kCannotPick)) { if (picked == this) { // cannot pick pad itself! - picked = 0; + picked = nullptr; } } @@ -4652,9 +4642,8 @@ void TPad::Print(const char *filename) const static Bool_t ContainsTImage(TList *li) { TIter next(li); - TObject *obj; - while ((obj = next())) { + while (auto obj = next()) { if (obj->InheritsFrom(TImage::Class())) { return kTRUE; } else if (obj->InheritsFrom(TPad::Class())) { @@ -5038,7 +5027,7 @@ void TPad::Print(const char *filename, Option_t *option) } delete gVirtualPS; - gVirtualPS = 0; + gVirtualPS = nullptr; padsav->cd(); return; @@ -5151,10 +5140,10 @@ void TPad::Print(const char *filename, Option_t *option) else Info("Print", "%s file %s has been closed", opt.Data(), psname.Data()); gROOT->GetListOfSpecials()->Remove(gVirtualPS); delete gVirtualPS; - gVirtualPS = 0; + gVirtualPS = nullptr; } else { Info("Print", "Current canvas added to %s file %s", opt.Data(), psname.Data()); - gVirtualPS = 0; + gVirtualPS = nullptr; } } @@ -6158,7 +6147,7 @@ struct dField { dField() - : fa(0), fb(0), fdist(0), fdir(' ') + : fa(nullptr), fb(nullptr), fdist(0), fdir(' ') {} dField(TAttBBox2D *a, TAttBBox2D *b, Int_t dist, char direction) @@ -6207,22 +6196,22 @@ void TPad::ShowGuidelines(TObject *object, const Int_t event, const char mode, c if (mode != 'i') resize = true; TPad *is_pad = dynamic_cast( object ); - TVirtualPad *padSave = 0; + TVirtualPad *padSave = nullptr; padSave = gPad; if (is_pad) if (is_pad->GetMother()) is_pad->GetMother()->cd(); - static TPad * tmpGuideLinePad; + static TPad *tmpGuideLinePad = nullptr; //delete all existing Guidelines and create new invisible pad if (tmpGuideLinePad) { if (object == tmpGuideLinePad) { // in case of funny button click combination. tmpGuideLinePad->Delete(); - tmpGuideLinePad = 0; + tmpGuideLinePad = nullptr; return; } tmpGuideLinePad->Delete(); - tmpGuideLinePad = 0; + tmpGuideLinePad = nullptr; } // Get Primitives @@ -6462,7 +6451,7 @@ void TPad::ShowGuidelines(TObject *object, const Int_t event, const char mode, c // All the arrows and lines in that pad are also deleted because // they all have the bit kCanDelete on. tmpGuideLinePad->Delete(); - tmpGuideLinePad = 0; + tmpGuideLinePad = nullptr; } break; } @@ -6905,7 +6894,7 @@ TObject *TPad::WaitPrimitive(const char *pname, const char *emode) //the following statement is required against other loop executions //before returning fCanvas->HandleInput((EEventType)-1,0,0); - return 0; + return nullptr; } } } @@ -6920,7 +6909,7 @@ TObject *TPad::WaitPrimitive(const char *pname, const char *emode) TObject *TPad::CreateToolTip(const TBox *box, const char *text, Long_t delayms) { - if (gPad->IsBatch()) return 0; + if (gPad->IsBatch()) return nullptr; return (TObject*)gROOT->ProcessLineFast(Form("new TGToolTip((TBox*)0x%zx,\"%s\",%d)", (size_t)box,text,(Int_t)delayms)); } @@ -7005,7 +6994,7 @@ TVirtualViewer3D *TPad::GetViewer3D(Option_t *type) } // Ensure we can create the new viewer before removing any existing one - TVirtualViewer3D *newViewer = 0; + TVirtualViewer3D *newViewer = nullptr; Bool_t createdExternal = kFALSE; From 5fca747ad6260fa42e281512d609e984008264d8 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 09:31:46 +0200 Subject: [PATCH 078/104] Fix memory leak in TPad::DrawCollideGrid and TPad::DrawColorTable Temporary TBox object was not deleted, now just in stack --- graf2d/gpad/src/TPad.cxx | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/graf2d/gpad/src/TPad.cxx b/graf2d/gpad/src/TPad.cxx index 6d57c9db2f2a7..24a212de75ee4 100644 --- a/graf2d/gpad/src/TPad.cxx +++ b/graf2d/gpad/src/TPad.cxx @@ -1632,12 +1632,12 @@ void TPad::DrawColorTable() gPad->Clear(); gPad->Range(x1,y1,x2,y2); - TText *text = new TText(0,0,""); - text->SetTextFont(61); - text->SetTextSize(0.07); - text->SetTextAlign(22); + TText text(0,0,""); + text.SetTextFont(61); + text.SetTextSize(0.07); + text.SetTextAlign(22); - TBox *box = new TBox(); + TBox box; // Draw color table boxes. hs = (y2-y1)/Double_t(5); @@ -1649,15 +1649,15 @@ void TPad::DrawColorTable() ylow = y1 + hs*(Double_t(j)+0.1); yup = y1 + hs*(Double_t(j)+0.9); color = 10*j + i; - box->SetFillStyle(1001); - box->SetFillColor(color); - box->DrawBox(xlow, ylow, xup, yup); - box->SetFillStyle(0); - box->SetLineColor(1); - box->DrawBox(xlow, ylow, xup, yup); - if (color == 1) text->SetTextColor(0); - else text->SetTextColor(1); - text->DrawText(0.5*(xlow+xup), 0.5*(ylow+yup), Form("%d",color)); + box.SetFillStyle(1001); + box.SetFillColor(color); + box.DrawBox(xlow, ylow, xup, yup); + box.SetFillStyle(0); + box.SetLineColor(1); + box.DrawBox(xlow, ylow, xup, yup); + if (color == 1) text.SetTextColor(0); + else text.SetTextColor(1); + text.DrawText(0.5*(xlow+xup), 0.5*(ylow+yup), Form("%d",color)); } } } @@ -3311,8 +3311,8 @@ void TPad::FillCollideGridTH1(TObject *o) void TPad::DrawCollideGrid() { if (fCGnx==0||fCGny==0) return; - auto box = new TBox(); - box->SetFillColorAlpha(kRed,0.5); + TBox box; + box.SetFillColorAlpha(kRed,0.5); Double_t xs = (fX2-fX1)/fCGnx; Double_t ys = (fY2-fY1)/fCGny; @@ -3342,11 +3342,11 @@ void TPad::DrawCollideGrid() Y2L = Y2; } if (!fCollideGrid[i + j*fCGnx]) { - box->SetFillColorAlpha(kBlack,t); - box->DrawBox(X1L, Y1L, X2L, Y2L); + box.SetFillColorAlpha(kBlack,t); + box.DrawBox(X1L, Y1L, X2L, Y2L); } else { - box->SetFillColorAlpha(kRed,t); - box->DrawBox(X1L, Y1L, X2L, Y2L); + box.SetFillColorAlpha(kRed,t); + box.DrawBox(X1L, Y1L, X2L, Y2L); } Y1 = Y2; Y2 = Y1+ys; From 9bce4e9571659802dcfbe3124af7484fd46252ad Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 09:42:07 +0200 Subject: [PATCH 079/104] Fix memory leaks in tmvagui Temporary TText object was not deleted, now used in stack --- tmva/tmvagui/src/BoostControlPlots.cxx | 10 +-- tmva/tmvagui/src/MovieMaker.cxx | 86 +++++++++++++------------- tmva/tmvagui/src/network.cxx | 80 ++++++++++++------------ 3 files changed, 88 insertions(+), 88 deletions(-) diff --git a/tmva/tmvagui/src/BoostControlPlots.cxx b/tmva/tmvagui/src/BoostControlPlots.cxx index d007e389f93d7..887be65ab15d2 100644 --- a/tmva/tmvagui/src/BoostControlPlots.cxx +++ b/tmva/tmvagui/src/BoostControlPlots.cxx @@ -121,11 +121,11 @@ void TMVA::boostcontrolplots(TString dataset, TDirectory *boostdir ) { legend->Draw("same"); } else { - TText* t = new TText(); - t->SetTextSize( 0.056 ); - t->SetTextColor( 2 ); - t->DrawTextNDC( .2, 0.6, "Use MethodBoost option: \"Boost_DetailedMonitoring\" " ); - t->DrawTextNDC( .2, 0.51, "to fill this histograms" ); + TText t; + t.SetTextSize( 0.056 ); + t.SetTextColor( 2 ); + t.DrawTextNDC( .2, 0.6, "Use MethodBoost option: \"Boost_DetailedMonitoring\" " ); + t.DrawTextNDC( .2, 0.51, "to fill this histograms" ); } c->Update(); diff --git a/tmva/tmvagui/src/MovieMaker.cxx b/tmva/tmvagui/src/MovieMaker.cxx index 3a52ada53ee99..cdbdeb9ccbede 100644 --- a/tmva/tmvagui/src/MovieMaker.cxx +++ b/tmva/tmvagui/src/MovieMaker.cxx @@ -32,20 +32,20 @@ void TMVA::DrawNetworkMovie(TString dataset, TFile* file, const TString& methodT std::vector epochList; Int_t ic = 0; while ((key = (TKey*)keyIt())) { - + if (!gROOT->GetClass(key->GetClassName())->InheritsFrom("TH2F")) continue; TString name = key->GetName(); - + if (!name.BeginsWith("epochmonitoring___")) continue; - + // extract epoch TObjArray* tokens = name.Tokenize("_"); TString es = ((TObjString*)tokens->At(2))->GetString(); - // check if done already + // check if done already Bool_t isOld = kFALSE; for (std::vector::const_iterator it = epochList.begin(); it < epochList.end(); ++it) { - if (*it == es) isOld = kTRUE; + if (*it == es) isOld = kTRUE; } if (isOld) continue; epochList.push_back( es ); @@ -78,7 +78,7 @@ void TMVA::DrawMLPoutputMovie(TString dataset, TFile* file, const TString& metho Float_t maxMult = 6.0; Int_t countCanvas = 0; Bool_t first = kTRUE; - + TString dirname = methodType + "/" + methodTitle + "/" + "EpochMonitoring"; TDirectory *epochDir = (TDirectory*)file->GetDirectory(dataset.Data())->Get( dirname ); if (!epochDir) { @@ -90,54 +90,54 @@ void TMVA::DrawMLPoutputMovie(TString dataset, TFile* file, const TString& metho TIter keyItTit(epochDir->GetListOfKeys()); TKey *titkeyTit; while ((titkeyTit = (TKey*)keyItTit())) { - + if (!gROOT->GetClass(titkeyTit->GetClassName())->InheritsFrom("TH1F")) continue; TString name = titkeyTit->GetName(); - + if (!name.BeginsWith("convergencetest___")) continue; if (!name.Contains("_train_")) continue; // only for training so far if (name.EndsWith( "_B")) continue; - + // must be signal histogram if (!name.EndsWith( "_S")) { cout << "Big troubles with histogram: " << name << " -> should end with _S" << endl; exit(1); } - + // create canvas countCanvas++; TString ctitle = Form("TMVA response %s",methodTitle.Data()); - c = new TCanvas( Form("canvas%d", countCanvas), ctitle, 0, 0, width, (Int_t)width*0.78 ); - + c = new TCanvas( Form("canvas%d", countCanvas), ctitle, 0, 0, width, (Int_t)width*0.78 ); + TH1F* sig = (TH1F*)titkeyTit->ReadObj(); sig->SetTitle( Form("TMVA response for classifier: %s", methodTitle.Data()) ); - + TString dataType = (name.Contains("_train_") ? "(training sample)" : "(test sample)"); - + // find background - TString nbn = sig->GetName(); nbn[nbn.Length()-1] = 'B'; + TString nbn = sig->GetName(); nbn[nbn.Length()-1] = 'B'; TH1F* bgd = dynamic_cast(epochDir->Get( nbn )); if (bgd == 0) { cout << "Big troubles with histogram: " << bgd << " -> cannot find!" << endl; exit(1); } - + cout << "sig = " << sig->GetName() << endl; cout << "bgd = " << bgd->GetName() << endl; - + // set the histogram style TMVAGlob::SetSignalAndBackgroundStyle( sig, bgd ); - + // normalise both signal and background TMVAGlob::NormalizeHists( sig, bgd ); - + // set only first time, then same for all plots if (first) { if (xmin == 0 && xmax == 0) { - xmin = TMath::Max( TMath::Min(sig->GetMean() - nrms*sig->GetRMS(), + xmin = TMath::Max( TMath::Min(sig->GetMean() - nrms*sig->GetRMS(), bgd->GetMean() - nrms*bgd->GetRMS() ), sig->GetXaxis()->GetXmin() ); - xmax = TMath::Min( TMath::Max(sig->GetMean() + nrms*sig->GetRMS(), + xmax = TMath::Min( TMath::Max(sig->GetMean() + nrms*sig->GetRMS(), bgd->GetMean() + nrms*bgd->GetRMS() ), sig->GetXaxis()->GetXmax() ); } @@ -145,18 +145,18 @@ void TMVA::DrawMLPoutputMovie(TString dataset, TFile* file, const TString& metho ymax = TMath::Max( sig->GetMaximum(), bgd->GetMaximum() )*maxMult; first = kFALSE; } - + // build a frame Int_t nb = 100; TString hFrameName(TString("frame") + methodTitle); TObject *o = gROOT->FindObject(hFrameName); if(o) delete o; - TH2F* frame = new TH2F( hFrameName, sig->GetTitle(), + TH2F* frame = new TH2F( hFrameName, sig->GetTitle(), nb, xmin, xmax, nb, ymin, ymax ); frame->GetXaxis()->SetTitle( methodTitle + " response" ); frame->GetYaxis()->SetTitle("(1/N) dN^{ }/^{ }dx"); TMVAGlob::SetFrameStyle( frame ); - + // find epoch number (4th token) TObjArray* tokens = name.Tokenize("_"); TString es = ((TObjString*)tokens->At(4))->GetString(); @@ -165,15 +165,15 @@ void TMVA::DrawMLPoutputMovie(TString dataset, TFile* file, const TString& metho exit(1); } Int_t epoch = es.Atoi(); - + // eventually: draw the frame - frame->Draw(); - + frame->Draw(); + c->GetPad(0)->SetLeftMargin( 0.105 ); frame->GetYaxis()->SetTitleOffset( 1.2 ); - - // Draw legend - TLegend *legend= new TLegend( c->GetLeftMargin(), 1 - c->GetTopMargin() - 0.12, + + // Draw legend + TLegend *legend= new TLegend( c->GetLeftMargin(), 1 - c->GetTopMargin() - 0.12, c->GetLeftMargin() + 0.5, 1 - c->GetTopMargin() ); legend->SetFillStyle( 1 ); legend->AddEntry(sig,TString("Signal ") + dataType, "F"); @@ -181,28 +181,28 @@ void TMVA::DrawMLPoutputMovie(TString dataset, TFile* file, const TString& metho legend->SetBorderSize(1); legend->SetMargin( 0.15 ); legend->Draw("same"); - - TText* t = new TText(); - t->SetTextSize( 0.04 ); - t->SetTextColor( 1 ); - t->SetTextAlign( 31 ); - t->DrawTextNDC( 1 - c->GetRightMargin(), 1 - c->GetTopMargin() + 0.015, Form( "Epoch: %i", epoch) ); - + + TText t; + t.SetTextSize( 0.04 ); + t.SetTextColor( 1 ); + t.SetTextAlign( 31 ); + t.DrawTextNDC( 1 - c->GetRightMargin(), 1 - c->GetTopMargin() + 0.015, Form( "Epoch: %i", epoch) ); + // overlay signal and background histograms sig->Draw("samehist"); bgd->Draw("samehist"); - + // save to file TString outdirname = "movieplots"; TString foutname = outdirname + "/" + name; foutname.Resize( foutname.Length()-2 ); foutname.ReplaceAll("convergencetest___",""); foutname += ".gif"; - + cout << "storing file: " << foutname << endl; - + c->Update(); - c->Print(foutname); + c->Print(foutname); } } @@ -211,9 +211,9 @@ void TMVA::DrawMLPoutputMovie(TString dataset, TFile* file, const TString& metho void TMVA::MovieMaker(TString dataset, TString methodType , TString methodTitle ) { TString fname = "TMVA.root"; - TFile* file = TMVAGlob::OpenFile( fname ); + TFile* file = TMVAGlob::OpenFile( fname ); //DrawMLPoutputMovie( file, methodType, methodTitle ); DrawNetworkMovie(dataset, file, methodType, methodTitle ); -} +} diff --git a/tmva/tmvagui/src/network.cxx b/tmva/tmvagui/src/network.cxx index b65b550346332..5acf76a8cd78a 100644 --- a/tmva/tmvagui/src/network.cxx +++ b/tmva/tmvagui/src/network.cxx @@ -26,7 +26,7 @@ static Int_t c_DarkBackground = TColor::GetColor( "#6e7a85" ); Bool_t MovieMode = kFALSE; -void TMVA::draw_network(TString dataset, TFile* f, TDirectory* d, const TString& hName, +void TMVA::draw_network(TString dataset, TFile* f, TDirectory* d, const TString& hName, Bool_t movieMode , const TString& epoch ) { Bool_t __PRINT_LOGO__ = kTRUE; @@ -47,14 +47,14 @@ void TMVA::draw_network(TString dataset, TFile* f, TDirectory* d, const TString& TMVAStyle->SetTitleFillColor( c_DarkBackground ); TMVAStyle->SetTitleTextColor( TColor::GetColor( "#FFFFFF" ) ); TMVAStyle->SetTitleBorderSize( 0 ); - + static Int_t icanvas = -1; Int_t ixc = 100 + (icanvas)*40; - Int_t iyc = 0 + (icanvas+1)*20; + Int_t iyc = 0 + (icanvas+1)*20; if (MovieMode) ixc = iyc = 0; TString canvasnumber = Form( "c%i", icanvas ); TString canvastitle = Form("Neural Network Layout for: %s", d->GetName()); - TCanvas* c = new TCanvas( canvasnumber, canvastitle, + TCanvas* c = new TCanvas( canvasnumber, canvastitle, ixc, 0 + (icanvas+1)*20, 1000, 650 ); icanvas++; TIter next = d->GetListOfKeys(); @@ -68,15 +68,15 @@ void TMVA::draw_network(TString dataset, TFile* f, TDirectory* d, const TString& while ((key = (TKey*)next())) { TClass *cl = gROOT->GetClass(key->GetClassName()); - if (!cl->InheritsFrom("TH2F")) + if (!cl->InheritsFrom("TH2F")) { - continue; + continue; }else { - std::cout<GetClassName()<<"----"<InheritsFrom("TH2F")<<"----"<GetClassName()<<"----"<InheritsFrom("TH2F")<<"----"<ReadObj(); + + TH2F* h = (TH2F*)key->ReadObj(); if (!h) { cout << "Big troubles in \"draw_network\" (1)" << endl; exit(1); @@ -84,7 +84,7 @@ void TMVA::draw_network(TString dataset, TFile* f, TDirectory* d, const TString& std::cout<GetName()<<"----"<GetName()).Contains( hName )){ numHists++; - + Int_t n1 = h->GetNbinsX(); Int_t n2 = h->GetNbinsY(); for (Int_t i = 0; i < n1; i++) { @@ -109,10 +109,10 @@ void TMVA::draw_network(TString dataset, TFile* f, TDirectory* d, const TString& //cout << "check4b" << endl; TClass *cl = gROOT->GetClass(key->GetClassName()); - if (!cl->InheritsFrom("TH2F")) continue; + if (!cl->InheritsFrom("TH2F")) continue; //cout << "check4c" << endl; - TH2F* h = (TH2F*)key->ReadObj(); + TH2F* h = (TH2F*)key->ReadObj(); //cout << (h->GetName()) << endl; if (!h) { cout << "Big troubles in \"draw_network\" (2)" << endl; @@ -130,17 +130,17 @@ void TMVA::draw_network(TString dataset, TFile* f, TDirectory* d, const TString& // add epoch if (MovieMode) { - TText* t = new TText(); - t->SetTextSize( 0.04 ); - t->SetTextColor( 0 ); - t->SetTextAlign( 31 ); - t->DrawTextNDC( 1 - c->GetRightMargin(), 1 - c->GetTopMargin() - 0.033, + TText t; + t.SetTextSize( 0.04 ); + t.SetTextColor( 0 ); + t.SetTextAlign( 31 ); + t.DrawTextNDC( 1 - c->GetRightMargin(), 1 - c->GetTopMargin() - 0.033, Form( "Epoch: %s", epoch.Data() ) ); } // ============================================================ if (__PRINT_LOGO__) TMVAGlob::plot_logo(); - // ============================================================ + // ============================================================ c->Update(); if (MovieMode) { @@ -150,9 +150,9 @@ void TMVA::draw_network(TString dataset, TFile* f, TDirectory* d, const TString& foutname.Resize( foutname.Length()-5 ); foutname.ReplaceAll("epochmonitoring___",""); foutname += ".gif"; - + cout << "storing file: " << foutname << endl; - c->Print(foutname); + c->Print(foutname); c->Clear(); delete c; } @@ -195,7 +195,7 @@ void TMVA::draw_layer_labels(Int_t nLayers) } } -void TMVA::draw_input_labels(TString dataset,Int_t nInputs, Double_t* cy, +void TMVA::draw_input_labels(TString dataset,Int_t nInputs, Double_t* cy, Double_t rad, Double_t layerWidth) { const Double_t LABEL_HEIGHT = 0.04; @@ -215,12 +215,12 @@ void TMVA::draw_input_labels(TString dataset,Int_t nInputs, Double_t* cy, Double_t x = margX + width; Double_t y = cy[i] - effHeight; - TText* t = new TText(); - t->SetTextColor(gStyle->GetTitleTextColor()); - t->SetTextAlign(31); - t->SetTextSize(LABEL_HEIGHT); - if (i == nInputs-1) t->SetTextColor( TColor::GetColor( "#AFDCEC" ) ); - t->DrawText( x, y+0.018, input + " :"); + TText t; + t.SetTextColor(gStyle->GetTitleTextColor()); + t.SetTextAlign(31); + t.SetTextSize(LABEL_HEIGHT); + if (i == nInputs-1) t.SetTextColor( TColor::GetColor( "#AFDCEC" ) ); + t.DrawText( x, y+0.018, input + " :"); } delete[] varNames; @@ -234,7 +234,7 @@ TString* TMVA::get_var_names(TString dataset, Int_t nVars ) "InputVariables_Id", "InputVariables_Norm", "InputVariables_Deco"}; - + TDirectory* dir = 0; for (Int_t i=0; i<6; i++) { dir = (TDirectory*)Network_GFile->GetDirectory(dataset.Data())->Get( directories[i] ); @@ -268,12 +268,12 @@ TString* TMVA::get_var_names(TString dataset, Int_t nVars ) if (!cl->InheritsFrom("TH1")) continue; TH1 *sig = (TH1*)key->ReadObj(); TString hname = sig->GetTitle(); - + vars[ivar] = hname; ivar++; if (ivar > nVars-1) break; - } - + } + if (ivar != nVars-1) { // bias layer and targets are also in nVars counts cout << "*** Troubles in \"network.cxx\": did not reproduce correct number of " << "input variables: " << ivar << " != " << nVars << endl; @@ -282,7 +282,7 @@ TString* TMVA::get_var_names(TString dataset, Int_t nVars ) return vars; } -void TMVA::draw_activation(TCanvas* c, Double_t cx, Double_t cy, +void TMVA::draw_activation(TCanvas* c, Double_t cx, Double_t cy, Double_t radx, Double_t rady, Int_t whichActivation) { TImage *activation = NULL; @@ -304,7 +304,7 @@ void TMVA::draw_activation(TCanvas* c, Double_t cx, Double_t cy, cout << "Could not create an image... exit" << endl; return; } - + activation->SetConstRatio(kFALSE); radx *= 0.7; @@ -319,7 +319,7 @@ void TMVA::draw_activation(TCanvas* c, Double_t cx, Double_t cy, c->cd(); } -void TMVA::draw_layer(TString dataset,TCanvas* c, TH2F* h, Int_t iHist, +void TMVA::draw_layer(TString dataset,TCanvas* c, TH2F* h, Int_t iHist, Int_t nLayers, Double_t maxWeight) { const Double_t MAX_NEURONS_NICE = 12; @@ -348,7 +348,7 @@ void TMVA::draw_layer(TString dataset,TCanvas* c, TH2F* h, Int_t iHist, if (iHist == 0) { - TEllipse *ellipse = new TEllipse( cx1, cy1[nNeurons1-i-1], + TEllipse *ellipse = new TEllipse( cx1, cy1[nNeurons1-i-1], effRad1*ratio, effRad1, 0, 360, 0 ); ellipse->SetFillColor(TColor::GetColor( "#fffffd" )); ellipse->SetFillStyle(1001); @@ -360,7 +360,7 @@ void TMVA::draw_layer(TString dataset,TCanvas* c, TH2F* h, Int_t iHist, Int_t whichActivation = 0; if (iHist==0 || iHist==nLayers-1 || i==0) whichActivation = 1; - draw_activation(c, cx1, cy1[nNeurons1-i-1], + draw_activation(c, cx1, cy1[nNeurons1-i-1], rad*ratio, rad, whichActivation); } } @@ -374,7 +374,7 @@ void TMVA::draw_layer(TString dataset,TCanvas* c, TH2F* h, Int_t iHist, for (Int_t i = 0; i < nNeurons2; i++) { cy2[nNeurons2-i-1] = i*(1.0-LABEL_HEIGHT)/nNeurons2 + 1.0/(2.0*nNeurons2) + LABEL_HEIGHT; - TEllipse *ellipse = + TEllipse *ellipse = new TEllipse(cx2, cy2[nNeurons2-i-1], effRad2*ratio, effRad2, 0, 360, 0); ellipse->SetFillColor(TColor::GetColor( "#fffffd" )); ellipse->SetFillStyle(1001); @@ -428,10 +428,10 @@ void TMVA::network(TString dataset, TString fin , Bool_t useTMVAStyle ) TMVAGlob::Initialize( useTMVAStyle ); // checks if file with name "fin" is already open, and if not opens one - TFile* file = TMVAGlob::OpenFile( fin ); + TFile* file = TMVAGlob::OpenFile( fin ); TIter next(file->GetDirectory(dataset.Data())->GetListOfKeys()); TKey *key(0); - while( (key = (TKey*)next()) ) { + while( (key = (TKey*)next()) ) { if (!TString(key->GetName()).BeginsWith("Method_MLP")) continue; if( ! gROOT->GetClass(key->GetClassName())->InheritsFrom("TDirectory") ) continue; @@ -445,7 +445,7 @@ void TMVA::network(TString dataset, TString fin , Bool_t useTMVAStyle ) if( ! gROOT->GetClass(titkey->GetClassName())->InheritsFrom("TDirectory") ) continue; TDirectory* dir = (TDirectory *)titkey->ReadObj(); - dir->cd(); + dir->cd(); TList titles; UInt_t ni = TMVAGlob::GetListOfTitles( dir, titles ); if (ni==0) { From b306a89ef1fe25663f8bfc809b3c3e736439d010 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 09:50:28 +0200 Subject: [PATCH 080/104] Fix temporary TText leaking in tutorials --- tutorials/graphics/archi.C | 26 +++++++------- tutorials/graphics/event.C | 20 +++++------ tutorials/graphics/pstable.C | 54 ++++++++++++++--------------- tutorials/hist/candleplotwhiskers.C | 17 ++++----- 4 files changed, 60 insertions(+), 57 deletions(-) diff --git a/tutorials/graphics/archi.C b/tutorials/graphics/archi.C index 1de2c637dc932..98419b2bc5691 100644 --- a/tutorials/graphics/archi.C +++ b/tutorials/graphics/archi.C @@ -215,18 +215,20 @@ void archi() { anal->Draw(); } } - TText *daq = new TText(); - daq->SetTextSize(0.07); - daq->SetTextAlign(22); - daq->DrawText(1.5,7.3,"DAQ"); - daq->DrawText(6,7.3,"DST"); - daq->DrawText(10.,7.3,"Physics Analysis"); - daq->DrawText(1.5,0.7,"Events"); - daq->DrawText(1.5,0.3,"Containers"); - daq->DrawText(6,0.7,"Tracks/Hits"); - daq->DrawText(6,0.3,"Containers"); - daq->DrawText(10.,0.7,"Attributes"); - daq->DrawText(10.,0.3,"Containers"); + + // just temporary object, used for common attributes + TText daq; + daq.SetTextSize(0.07); + daq.SetTextAlign(22); + daq.DrawText(1.5,7.3,"DAQ"); + daq.DrawText(6,7.3,"DST"); + daq.DrawText(10.,7.3,"Physics Analysis"); + daq.DrawText(1.5,0.7,"Events"); + daq.DrawText(1.5,0.3,"Containers"); + daq.DrawText(6,0.7,"Tracks/Hits"); + daq.DrawText(6,0.3,"Containers"); + daq.DrawText(10.,0.7,"Attributes"); + daq.DrawText(10.,0.3,"Containers"); c1->cd(); } diff --git a/tutorials/graphics/event.C b/tutorials/graphics/event.C index 6bb49c4889ed7..018a8e350ed6d 100644 --- a/tutorials/graphics/event.C +++ b/tutorials/graphics/event.C @@ -62,14 +62,14 @@ void event(){ p6->SetFillColor(42); p6->AddText("10 bytes"); p6->Draw(); - TText *text = new TText(); - text->SetTextAlign(12); - text->SetTextSize(0.04); - text->SetTextFont(72); - text->DrawText(6.2,11.5,"Header:Event_flag"); - text->DrawText(7.2,9.5,"Trigger_Info"); - text->DrawText(8.2,7.5,"Muon_Detector: TOF"); - text->DrawText(9.2,5.5,"Calorimeters"); - text->DrawText(10.2,3.5,"Forward_Detectors"); - text->DrawText(11.2,1.5,"TPCs"); + TText text; + text.SetTextAlign(12); + text.SetTextSize(0.04); + text.SetTextFont(72); + text.DrawText(6.2,11.5,"Header:Event_flag"); + text.DrawText(7.2,9.5,"Trigger_Info"); + text.DrawText(8.2,7.5,"Muon_Detector: TOF"); + text.DrawText(9.2,5.5,"Calorimeters"); + text.DrawText(10.2,3.5,"Forward_Detectors"); + text.DrawText(11.2,1.5,"TPCs"); } diff --git a/tutorials/graphics/pstable.C b/tutorials/graphics/pstable.C index e68263ef1d641..5237c87047f2d 100644 --- a/tutorials/graphics/pstable.C +++ b/tutorials/graphics/pstable.C @@ -7,7 +7,7 @@ /// /// \author Olivier Couet -void table(Float_t x1, Float_t x2, Float_t yrange, TText *t, const char **symbol, Bool_t octal); +void table(Float_t x1, Float_t x2, Float_t yrange, TText &t, const char **symbol, Bool_t octal); void pstable() { @@ -55,18 +55,18 @@ void pstable() TCanvas *c1 = new TCanvas("c1","c1",200,10,w,h); c1->Range(0,0,xrange,yrange); - TText *t = new TText(0,0,"a"); - t->SetTextSize(0.02); - t->SetTextFont(62); - t->SetTextAlign(22); + TText t(0,0,"a"); + t.SetTextSize(0.02); + t.SetTextFont(62); + t.SetTextAlign(22); table(0.5,0.5*xrange-0.5,yrange,t,symbol1,0); table(0.5*xrange+0.5,xrange-0.5,yrange,t,symbol2,0); - TText *tlabel = new TText(0,0,"a"); - tlabel->SetTextFont(72); - tlabel->SetTextSize(0.018); - tlabel->SetTextAlign(22); - tlabel->DrawText(0.5*xrange,1.3, + TText tlabel(0,0,"a"); + tlabel.SetTextFont(72); + tlabel.SetTextSize(0.018); + tlabel.SetTextAlign(22); + tlabel.DrawText(0.5*xrange,1.3, "Input characters are standard keyboard characters"); c1->Modified(); c1->Update(); @@ -77,7 +77,7 @@ void pstable() table(0.5,0.5*xrange-0.5,yrange,t,symbol3,1); table(0.5*xrange+0.5,xrange-0.5,yrange,t,symbol4,1); - tlabel->DrawText(0.5*xrange,1.3, + tlabel.DrawText(0.5*xrange,1.3, "Input characters using backslash and octal numbers"); c2->Modified(); c2->Update(); @@ -87,13 +87,13 @@ void pstable() c3->Range(0,0,xrange,yrange); table(0.5,0.5*xrange-0.5,yrange,t,symbol5,1); - tlabel->DrawText(0.5*xrange,1.3, + tlabel.DrawText(0.5*xrange,1.3, "Input characters using backslash and octal numbers"); c3->Modified(); c3->Update(); c3->Print("pstable3.ps"); } -void table(Float_t x1, Float_t x2, Float_t yrange, TText *t, +void table(Float_t x1, Float_t x2, Float_t yrange, TText &t, const char **symbol, Bool_t octal) { Int_t i; @@ -122,15 +122,15 @@ void table(Float_t x1, Float_t x2, Float_t yrange, TText *t, line->DrawLine(x1+2*dx,y1,x1+2*dx,y2); line->DrawLine(x1+3*dx,y1,x1+3*dx,y2); line->DrawLine(x1+4*dx,y1,x1+4*dx,y2); - TText *tit = new TText(0,0,"a"); - tit->SetTextSize(0.015); - tit->SetTextFont(72); - tit->SetTextAlign(22); - tit->DrawText(xc0,y2-0.6,"Input"); - tit->DrawText(xc1,y2-0.6,"Roman"); - tit->DrawText(xc2,y2-0.6,"Greek"); - tit->DrawText(xc3,y2-0.6,"Special"); - tit->DrawText(xc4,y2-0.6,"Zapf"); + TText tit(0,0,"a"); + tit.SetTextSize(0.015); + tit.SetTextFont(72); + tit.SetTextAlign(22); + tit.DrawText(xc0,y2-0.6,"Input"); + tit.DrawText(xc1,y2-0.6,"Roman"); + tit.DrawText(xc2,y2-0.6,"Greek"); + tit.DrawText(xc3,y2-0.6,"Special"); + tit.DrawText(xc4,y2-0.6,"Zapf"); char text[12]; for (i=0;iDrawText(xc0,y,text); + t.DrawText(xc0,y,text); sprintf(text,"%s",symbol[i]); - t->DrawText(xc1,y,text); + t.DrawText(xc1,y,text); sprintf(text,"`%s",symbol[i]); - t->DrawText(xc2,y,text); + t.DrawText(xc2,y,text); sprintf(text,"'%s",symbol[i]); - t->DrawText(xc3,y,text); + t.DrawText(xc3,y,text); sprintf(text,"~%s",symbol[i]); - t->DrawText(xc4,y,text); + t.DrawText(xc4,y,text); y -= dy; } } diff --git a/tutorials/hist/candleplotwhiskers.C b/tutorials/hist/candleplotwhiskers.C index d142eb8e0a829..8e709602316b2 100644 --- a/tutorials/hist/candleplotwhiskers.C +++ b/tutorials/hist/candleplotwhiskers.C @@ -66,12 +66,13 @@ void candleplotwhiskers() { mygaus_1_middle->Draw("same"); //In principal one could calculate these values by h2->Integral() as well - auto t = new TText(); t->SetTextFont(42); - t->DrawText(0,mygaus_1_middle->Eval(0)/2,"50%"); - t->DrawText(-1.5,mygaus_1_middle->Eval(-1.5)/2,"24.65%"); - t->DrawText(+1,mygaus_1_middle->Eval(+1.5)/2,"24.65%"); - t->DrawText(q[0]-1.5*iqr,1000,Form("%.3f",q[0]-1.5*iqr))->SetTextAngle(90); - t->DrawText(q[2]+1.5*iqr,1000,Form("%.3f",q[2]+1.5*iqr))->SetTextAngle(90); - t->DrawText(q[0],1000,Form("%.3f",q[0]))->SetTextAngle(90); - t->DrawText(q[2],1000,Form("%.3f",q[2]))->SetTextAngle(90); + TText t; + t.SetTextFont(42); + t.DrawText(0,mygaus_1_middle->Eval(0)/2,"50%"); + t.DrawText(-1.5,mygaus_1_middle->Eval(-1.5)/2,"24.65%"); + t.DrawText(+1,mygaus_1_middle->Eval(+1.5)/2,"24.65%"); + t.DrawText(q[0]-1.5*iqr,1000,Form("%.3f",q[0]-1.5*iqr))->SetTextAngle(90); + t.DrawText(q[2]+1.5*iqr,1000,Form("%.3f",q[2]+1.5*iqr))->SetTextAngle(90); + t.DrawText(q[0],1000,Form("%.3f",q[0]))->SetTextAngle(90); + t.DrawText(q[2],1000,Form("%.3f",q[2]))->SetTextAngle(90); } From 792d9b5aac2d821cac283c35344b1e281c330b74 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 10:03:45 +0200 Subject: [PATCH 081/104] Fix TLatex memory leak in stressGraphics --- test/stressGraphics.cxx | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/test/stressGraphics.cxx b/test/stressGraphics.cxx index b27252836ffd4..9db999f7de4a8 100644 --- a/test/stressGraphics.cxx +++ b/test/stressGraphics.cxx @@ -1532,22 +1532,22 @@ void tgaxis5() double f = 1.8; - TLatex* tex1 = new TLatex; - tex1->SetNDC(); - tex1->SetTextFont(102); - tex1->SetTextSize(0.07*f); - - TLatex* tex3 = new TLatex; - tex3->SetNDC(); - tex3->SetTextFont(102); - tex3->SetTextSize(0.07*f); - tex3->SetTextColor(kBlue+2); - - TLatex* tex2 = new TLatex; - tex2->SetNDC(); - tex2->SetTextFont(102); - tex2->SetTextSize(0.07*f); - tex2->SetTextColor(kOrange+3); + TLatex tex1; + tex1.SetNDC(); + tex1.SetTextFont(102); + tex1.SetTextSize(0.07*f); + + TLatex tex3; + tex3.SetNDC(); + tex3.SetTextFont(102); + tex3.SetTextSize(0.07*f); + tex3.SetTextColor(kBlue+2); + + TLatex tex2; + tex2.SetNDC(); + tex2.SetTextFont(102); + tex2.SetTextSize(0.07*f); + tex2.SetTextColor(kOrange+3); time_t offset[] = {0, 0, 1325376000, 1341100800}; time_t t[] = {1331150400, 1336417200, 0, 36000}; @@ -1595,11 +1595,11 @@ void tgaxis5() sprintf(buf, "#splitline{%d h %d m %d s}{offset: %s, option %s}", h, m, s, stime(offset + i, gmt).Data(), opt); } - tex1->DrawLatex(.01, .75, buf); - tex2->DrawLatex(.01, .50, offsettimeformat); + tex1.DrawLatex(.01, .75, buf); + tex2.DrawLatex(.01, .50, offsettimeformat); time_t t_ = t[i] + offset[i]; sprintf(buf, "Expecting: #color[2]{%s}", stime(&t_, gmt, false).Data()); - tex3->DrawLatex(.01, .24, buf); + tex3.DrawLatex(.01, .24, buf); if(i > 0) l.DrawLine(0, 0.95, 1, 0.95); } } From 4b38e64613b05533e4182a92e280c2d12b67e1fe Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 10:04:29 +0200 Subject: [PATCH 082/104] Fix TLatex memory leak in tutorials and demos --- graf2d/graf/doc/macros/alignment.C | 48 +++++------ hist/histpainter/src/THistPainter.cxx | 6 +- tutorials/graphics/AtlasExample.C | 6 +- tutorials/graphs/timeonaxis3.C | 34 ++++---- tutorials/graphs/zdemo.C | 117 +++++++++++++------------- tutorials/hist/h2proj.C | 10 +-- 6 files changed, 111 insertions(+), 110 deletions(-) diff --git a/graf2d/graf/doc/macros/alignment.C b/graf2d/graf/doc/macros/alignment.C index dd6f989f6c62d..c3d3fbc7c5dce 100644 --- a/graf2d/graf/doc/macros/alignment.C +++ b/graf2d/graf/doc/macros/alignment.C @@ -5,33 +5,33 @@ TCanvas *alignment() Tlva->DrawFrame(0,0,1,1); const char *longstring = "K_{S}... K^{*0}... #frac{2s}{#pi#alpha^{2}} #frac{d#sigma}{dcos#theta} (e^{+}e^{-} #rightarrow f#bar{f} ) = #left| #frac{1}{1 - #Delta#alpha} #right|^{2} (1+cos^{2}#theta)"; - TLatex *latex = new TLatex(); - latex->SetTextSize(0.025); - latex->SetTextAlign(13); //align at top - latex->DrawLatex(.2,.9,"K_{S}"); - latex->DrawLatex(.3,.9,"K^{*0}"); - latex->DrawLatex(.2,.8,longstring); + TLatex latex; + latex.SetTextSize(0.025); + latex.SetTextAlign(13); //align at top + latex.DrawLatex(.2,.9,"K_{S}"); + latex.DrawLatex(.3,.9,"K^{*0}"); + latex.DrawLatex(.2,.8,longstring); - latex->SetTextAlign(12); //centered - latex->DrawLatex(.2,.6,"K_{S}"); - latex->DrawLatex(.3,.6,"K^{*0}"); - latex->DrawLatex(.2,.5,longstring); + latex.SetTextAlign(12); //centered + latex.DrawLatex(.2,.6,"K_{S}"); + latex.DrawLatex(.3,.6,"K^{*0}"); + latex.DrawLatex(.2,.5,longstring); - latex->SetTextAlign(11); //default bottom alignment - latex->DrawLatex(.2,.4,"K_{S}"); - latex->DrawLatex(.3,.4,"K^{*0}"); - latex->DrawLatex(.2,.3,longstring); + latex.SetTextAlign(11); //default bottom alignment + latex.DrawLatex(.2,.4,"K_{S}"); + latex.DrawLatex(.3,.4,"K^{*0}"); + latex.DrawLatex(.2,.3,longstring); - latex->SetTextAlign(10); //special bottom alignment - latex->DrawLatex(.2,.2,"K_{S}"); - latex->DrawLatex(.3,.2,"K^{*0}"); - latex->DrawLatex(.2,.1,longstring); + latex.SetTextAlign(10); //special bottom alignment + latex.DrawLatex(.2,.2,"K_{S}"); + latex.DrawLatex(.3,.2,"K^{*0}"); + latex.DrawLatex(.2,.1,longstring); - latex->SetTextAlign(12); - latex->SetTextFont(72); - latex->DrawLatex(.1,.80,"13"); - latex->DrawLatex(.1,.55,"12"); - latex->DrawLatex(.1,.35,"11"); - latex->DrawLatex(.1,.18,"10"); + latex.SetTextAlign(12); + latex.SetTextFont(72); + latex.DrawLatex(.1,.80,"13"); + latex.DrawLatex(.1,.55,"12"); + latex.DrawLatex(.1,.35,"11"); + latex.DrawLatex(.1,.18,"10"); return Tlva; } diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx index eed9036898a86..bb792f8c4a772 100644 --- a/hist/histpainter/src/THistPainter.cxx +++ b/hist/histpainter/src/THistPainter.cxx @@ -1005,19 +1005,19 @@ Begin_Macro(source) hf->Fill(5,23); auto hf_copy1 = hf->Clone("hf_copy1"); - auto lt = new TLatex(); + TLatex lt; auto cx = new TCanvas(); cx->Divide(2,1); cx->cd(1); h2->Draw("box"); hf->Draw("text colz same"); - lt->DrawLatexNDC(0.3,0.5,"SAME"); + lt.DrawLatexNDC(0.3,0.5,"SAME"); cx->cd(2); h2->Draw("box"); hf_copy1->Draw("text colz same0"); - lt->DrawLatexNDC(0.3,0.5,"SAME0"); + lt.DrawLatexNDC(0.3,0.5,"SAME0"); } End_Macro diff --git a/tutorials/graphics/AtlasExample.C b/tutorials/graphics/AtlasExample.C index 6d81711abd465..202f0490fa2a4 100644 --- a/tutorials/graphics/AtlasExample.C +++ b/tutorials/graphics/AtlasExample.C @@ -101,9 +101,9 @@ void AtlasExample() data[icut]->Draw("P"); } - auto t = new TLatex; t->SetNDC(); - t->DrawLatex(0.3, 0.85, "#sqrt{s}= 14 TeV"); - t->DrawLatex(0.57, 0.85, "|#eta_{jet}|<0.5"); + TLatex t; t.SetNDC(); + t.DrawLatex(0.3, 0.85, "#sqrt{s}= 14 TeV"); + t.DrawLatex(0.57, 0.85, "|#eta_{jet}|<0.5"); auto l = new TLegend(0.45,0.65,0.8,0.8,"","NDC"); l->SetBorderSize(0.); diff --git a/tutorials/graphs/timeonaxis3.C b/tutorials/graphs/timeonaxis3.C index 44c0ac96860d6..63cf85e74515a 100644 --- a/tutorials/graphs/timeonaxis3.C +++ b/tutorials/graphs/timeonaxis3.C @@ -36,22 +36,22 @@ TCanvas *timeonaxis3() { TCanvas* c = new TCanvas; - TLatex* tex1 = new TLatex; - tex1->SetNDC(); - tex1->SetTextFont(102); - tex1->SetTextSize(0.055*f); + TLatex tex1; + tex1.SetNDC(); + tex1.SetTextFont(102); + tex1.SetTextSize(0.055*f); - TLatex* tex3 = new TLatex; - tex3->SetNDC(); - tex3->SetTextFont(102); - tex3->SetTextSize(0.07*f); - tex3->SetTextColor(kBlue+2); + TLatex tex3; + tex3.SetNDC(); + tex3.SetTextFont(102); + tex3.SetTextSize(0.07*f); + tex3.SetTextColor(kBlue+2); - TLatex* tex2 = new TLatex; - tex2->SetNDC(); - tex2->SetTextFont(102); - tex2->SetTextSize(0.07*f); - tex2->SetTextColor(kOrange+3); + TLatex tex2; + tex2.SetNDC(); + tex2.SetTextFont(102); + tex2.SetTextSize(0.07*f); + tex2.SetTextColor(kOrange+3); time_t offset[] = {0, 0, 1325376000, 1341100800}; time_t t[] = {1331150400, 1336417200, 0, 36000}; @@ -99,11 +99,11 @@ TCanvas *timeonaxis3() { sprintf(buf, "#splitline{%d h %d m %d s}{offset: %s, option %s}", h, m, s, stime(offset + i, gmt).Data(), opt); } - tex1->DrawLatex(.01, .75, buf); - tex2->DrawLatex(.01, .50, offsettimeformat); + tex1.DrawLatex(.01, .75, buf); + tex2.DrawLatex(.01, .50, offsettimeformat); time_t t_ = t[i] + offset[i]; sprintf(buf, "Expecting: #color[2]{%s}", stime(&t_, gmt, false).Data()); - tex3->DrawLatex(.01, .24, buf); + tex3.DrawLatex(.01, .24, buf); if(i > 0) l.DrawLine(0, 0.95, 1, 0.95); } } diff --git a/tutorials/graphs/zdemo.C b/tutorials/graphs/zdemo.C index 8a08e074181b6..f1faaf53d9998 100644 --- a/tutorials/graphs/zdemo.C +++ b/tutorials/graphs/zdemo.C @@ -59,13 +59,13 @@ void zdemo() pl->SetTextColor(49); pl->Draw(); - TLatex *t = new TLatex(); - t->SetTextFont(32); - t->SetTextColor(1); - t->SetTextSize(0.03); - t->SetTextAlign(12); - t->DrawLatex(3.1,15.5,"M.Tokarev, E.Potrebenikova "); - t->DrawLatex(14.,15.5,"JINR preprint E2-98-64, Dubna, 1998 "); + TLatex t0; + t0.SetTextFont(32); + t0.SetTextColor(1); + t0.SetTextSize(0.03); + t0.SetTextAlign(12); + t0.DrawLatex(3.1,15.5,"M.Tokarev, E.Potrebenikova "); + t0.DrawLatex(14.,15.5,"JINR preprint E2-98-64, Dubna, 1998 "); TPad *pad1 = new TPad("pad1","This is pad1",0.02,0.02,0.48,0.83,33); TPad *pad2 = new TPad("pad2","This is pad2",0.52,0.02,0.98,0.83,33); @@ -92,32 +92,33 @@ void zdemo() // create a 2-d histogram to define the range pad1->DrawFrame(1,1e-18,110,1e-8); pad1->GetFrame()->SetFillColor(19); - t = new TLatex(); - t->SetNDC(); - t->SetTextFont(62); - t->SetTextColor(36); - t->SetTextSize(0.08); - t->SetTextAlign(12); - t->DrawLatex(0.6,0.85,"p - p"); - - t->SetTextSize(0.05); - t->DrawLatex(0.6,0.79,"Direct #gamma"); - t->DrawLatex(0.6,0.75,"#theta = 90^{o}"); - - t->DrawLatex(0.20,0.45,"Ed^{3}#sigma/dq^{3}"); - t->DrawLatex(0.18,0.40,"(barn/Gev^{2})"); - - t->SetTextSize(0.045); - t->SetTextColor(kBlue); - t->DrawLatex(0.22,0.260,"#sqrt{s} = 63(GeV)"); - t->SetTextColor(kRed); - t->DrawLatex(0.22,0.205,"#sqrt{s} = 200(GeV)"); - t->SetTextColor(6); - t->DrawLatex(0.22,0.15,"#sqrt{s} = 500(GeV)"); - - t->SetTextSize(0.05); - t->SetTextColor(1); - t->DrawLatex(0.6,0.06,"q_{T} (Gev/c)"); + + TLatex t1; + t1.SetNDC(); + t1.SetTextFont(62); + t1.SetTextColor(36); + t1.SetTextSize(0.08); + t1.SetTextAlign(12); + t1.DrawLatex(0.6,0.85,"p - p"); + + t1.SetTextSize(0.05); + t1.DrawLatex(0.6,0.79,"Direct #gamma"); + t1.DrawLatex(0.6,0.75,"#theta = 90^{o}"); + + t1.DrawLatex(0.20,0.45,"Ed^{3}#sigma/dq^{3}"); + t1.DrawLatex(0.18,0.40,"(barn/Gev^{2})"); + + t1.SetTextSize(0.045); + t1.SetTextColor(kBlue); + t1.DrawLatex(0.22,0.260,"#sqrt{s} = 63(GeV)"); + t1.SetTextColor(kRed); + t1.DrawLatex(0.22,0.205,"#sqrt{s} = 200(GeV)"); + t1.SetTextColor(6); + t1.DrawLatex(0.22,0.15,"#sqrt{s} = 500(GeV)"); + + t1.SetTextSize(0.05); + t1.SetTextColor(1); + t1.DrawLatex(0.6,0.06,"q_{T} (Gev/c)"); TGraph *gr1 = new TGraph(NLOOP,PT,INVSIG); @@ -206,31 +207,31 @@ void zdemo() gr->SetMarkerSize(1.5); gr->Draw("LP"); - t = new TLatex(); - t->SetNDC(); - t->SetTextFont(62); - t->SetTextColor(36); - t->SetTextSize(0.08); - t->SetTextAlign(12); - t->DrawLatex(0.6,0.85,"p - p"); - - t->SetTextSize(0.05); - t->DrawLatex(0.6,0.79,"Direct #gamma"); - t->DrawLatex(0.6,0.75,"#theta = 90^{o}"); - - t->DrawLatex(0.70,0.55,"H(z)"); - t->DrawLatex(0.68,0.50,"(barn)"); - - t->SetTextSize(0.045); - t->SetTextColor(46); - t->DrawLatex(0.20,0.30,"#sqrt{s}, GeV"); - t->DrawLatex(0.22,0.26,"63"); - t->DrawLatex(0.22,0.22,"200"); - t->DrawLatex(0.22,0.18,"500"); - - t->SetTextSize(0.05); - t->SetTextColor(1); - t->DrawLatex(0.88,0.06,"z"); + TLatex t2; + t2.SetNDC(); + t2.SetTextFont(62); + t2.SetTextColor(36); + t2.SetTextSize(0.08); + t2.SetTextAlign(12); + t2.DrawLatex(0.6,0.85,"p - p"); + + t2.SetTextSize(0.05); + t2.DrawLatex(0.6,0.79,"Direct #gamma"); + t2.DrawLatex(0.6,0.75,"#theta = 90^{o}"); + + t2.DrawLatex(0.70,0.55,"H(z)"); + t2.DrawLatex(0.68,0.50,"(barn)"); + + t2.SetTextSize(0.045); + t2.SetTextColor(46); + t2.DrawLatex(0.20,0.30,"#sqrt{s}, GeV"); + t2.DrawLatex(0.22,0.26,"63"); + t2.DrawLatex(0.22,0.22,"200"); + t2.DrawLatex(0.22,0.18,"500"); + + t2.SetTextSize(0.05); + t2.SetTextColor(1); + t2.DrawLatex(0.88,0.06,"z"); c1->Modified(); c1->Update(); diff --git a/tutorials/hist/h2proj.C b/tutorials/hist/h2proj.C index dabbacefef333..81850ed19a975 100644 --- a/tutorials/hist/h2proj.C +++ b/tutorials/hist/h2proj.C @@ -51,11 +51,11 @@ void h2proj() projh2Y->Draw("hbar"); c1->cd(); - TLatex *t = new TLatex(); - t->SetTextFont(42); - t->SetTextSize(0.02); - t->DrawLatex(0.6,0.88,"This example demonstrates how to display"); - t->DrawLatex(0.6,0.85,"a histogram and its two projections."); + TLatex t; + t.SetTextFont(42); + t.SetTextSize(0.02); + t.DrawLatex(0.6,0.88,"This example demonstrates how to display"); + t.DrawLatex(0.6,0.85,"a histogram and its two projections."); auto ex = new TExec("zoom","ZoomExec()"); h2->GetListOfFunctions()->Add(ex); From a8567a3f4e0d9017149afc4729d1ccf042ded2d4 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 10:11:52 +0200 Subject: [PATCH 083/104] Fix TLine::DrawLine memory leaks in tutorials and demos --- core/base/doc/macros/textalign.C | 13 +++++++------ core/base/doc/macros/textangle.C | 24 ++++++++++++------------ tutorials/graphics/pstable.C | 20 ++++++++++---------- tutorials/tree/tree.C | 2 +- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/core/base/doc/macros/textalign.C b/core/base/doc/macros/textalign.C index 1c9b9989bbc79..05b70c5084f71 100644 --- a/core/base/doc/macros/textalign.C +++ b/core/base/doc/macros/textalign.C @@ -2,12 +2,13 @@ auto *Ta = new TCanvas("Ta","Ta",0,0,500,200); Ta->Range(0,0,1,1); - auto *lv = new TLine; - lv->SetLineStyle(3); lv->SetLineColor(kBlue); - lv->DrawLine(0.33,0.0,0.33,1.0); - lv->DrawLine(0.6,0.165,1.,0.165); - lv->DrawLine(0.6,0.493,1.,0.493); - lv->DrawLine(0.6,0.823,1.,0.823); + TLine lv; + lv.SetLineStyle(3); + lv.SetLineColor(kBlue); + lv.DrawLine(0.33,0.0,0.33,1.0); + lv.DrawLine(0.6,0.165,1.,0.165); + lv.DrawLine(0.6,0.493,1.,0.493); + lv.DrawLine(0.6,0.823,1.,0.823); // Horizontal alignment. auto *th1 = new TText(0.33,0.165,"Left adjusted"); diff --git a/core/base/doc/macros/textangle.C b/core/base/doc/macros/textangle.C index 1b9175c2dcf98..b8b144ccd1d45 100644 --- a/core/base/doc/macros/textangle.C +++ b/core/base/doc/macros/textangle.C @@ -1,18 +1,18 @@ { auto *Ta = new TCanvas("Ta","Text angle",0,0,300,326); Ta->Range(0,0,1,1); - auto *l = new TLine(); - l->SetLineColor(kRed); - l->DrawLine(0.1,0.1,0.9,0.1); - l->DrawLine(0.1,0.1,0.9,0.9); - auto *m = new TMarker(); - m->SetMarkerStyle(20); - m->SetMarkerColor(kBlue); - m->DrawMarker(0.1,0.1); - auto *a = new TArc(); - a->SetFillStyle(0); - a->SetLineColor(kBlue); a->SetLineStyle(3); - a->DrawArc(0.1, 0.1, 0.2, 0.,45.,"only"); + TLine l; + l.SetLineColor(kRed); + l.DrawLine(0.1,0.1,0.9,0.1); + l.DrawLine(0.1,0.1,0.9,0.9); + TMarker m; + m.SetMarkerStyle(20); + m.SetMarkerColor(kBlue); + m.DrawMarker(0.1,0.1); + TArc a; + a.SetFillStyle(0); + a.SetLineColor(kBlue); a->SetLineStyle(3); + a.DrawArc(0.1, 0.1, 0.2, 0.,45.,"only"); auto *tt = new TText(0.1,0.1,"Text angle is 45 degrees"); tt->SetTextAlign(11); tt->SetTextSize(0.1); tt->SetTextAngle(45); diff --git a/tutorials/graphics/pstable.C b/tutorials/graphics/pstable.C index 5237c87047f2d..cb595f9908cc9 100644 --- a/tutorials/graphics/pstable.C +++ b/tutorials/graphics/pstable.C @@ -112,16 +112,16 @@ void table(Float_t x1, Float_t x2, Float_t yrange, TText &t, Float_t xc2 = xc1 + dx; Float_t xc3 = xc2 + dx; Float_t xc4 = xc3 + dx; - TLine *line = new TLine(); - line->DrawLine(x1,y1,x1,y2); - line->DrawLine(x1,y1,x2,y1); - line->DrawLine(x1,y2,x2,y2); - line->DrawLine(x2,y1,x2,y2); - line->DrawLine(x1,y2-1,x2,y2-1); - line->DrawLine(x1+ dx,y1,x1+ dx,y2); - line->DrawLine(x1+2*dx,y1,x1+2*dx,y2); - line->DrawLine(x1+3*dx,y1,x1+3*dx,y2); - line->DrawLine(x1+4*dx,y1,x1+4*dx,y2); + TLine line; + line.DrawLine(x1,y1,x1,y2); + line.DrawLine(x1,y1,x2,y1); + line.DrawLine(x1,y2,x2,y2); + line.DrawLine(x2,y1,x2,y2); + line.DrawLine(x1,y2-1,x2,y2-1); + line.DrawLine(x1+ dx,y1,x1+ dx,y2); + line.DrawLine(x1+2*dx,y1,x1+2*dx,y2); + line.DrawLine(x1+3*dx,y1,x1+3*dx,y2); + line.DrawLine(x1+4*dx,y1,x1+4*dx,y2); TText tit(0,0,"a"); tit.SetTextSize(0.015); tit.SetTextFont(72); diff --git a/tutorials/tree/tree.C b/tutorials/tree/tree.C index 105dcd5fa478f..22d603e0f8696 100644 --- a/tutorials/tree/tree.C +++ b/tutorials/tree/tree.C @@ -2,7 +2,7 @@ /// \ingroup tutorial_tree /// \notebook /// Display the Tree data structures -/// +/// /// \macro_image /// \macro_code /// From 702cf95621b5b1e51c223ed889811c3c7c6556b6 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 10:15:22 +0200 Subject: [PATCH 084/104] Fix TArrow::DrawArrow memory leak in tutorials --- tutorials/graphics/archi.C | 30 +++++++++++++++--------------- tutorials/tree/tree.C | 30 +++++++++++++++--------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/tutorials/graphics/archi.C b/tutorials/graphics/archi.C index 98419b2bc5691..d6783f21ebe91 100644 --- a/tutorials/graphics/archi.C +++ b/tutorials/graphics/archi.C @@ -109,13 +109,13 @@ void archi() { tstub2->SetTextAlign(22); tstub2->SetTextAngle(-90); tstub2->Draw(); - TArrow *ar1 = new TArrow(); - ar1->SetLineWidth(6); - ar1->SetLineColor(1); - ar1->SetFillStyle(1001); - ar1->SetFillColor(1); - ar1->DrawArrow(13.5,14,15,14,0.012,"|>"); - ar1->DrawArrow(15.1,13,13.51,13,0.012,"|>"); + TArrow ar1; + ar1.SetLineWidth(6); + ar1.SetLineColor(1); + ar1.SetFillStyle(1001); + ar1.SetFillColor(1); + ar1.DrawArrow(13.5,14,15,14,0.012,"|>"); + ar1.DrawArrow(15.1,13,13.51,13,0.012,"|>"); TPaveText *cint = new TPaveText(1.0,15.0,8.0,17.5); cint->SetFillColor(39); @@ -173,14 +173,14 @@ void archi() { box2->SetLineStyle(3); box2->Draw(); - ar1->DrawArrow(2.5,17.5,2.5,18.9,0.012,"|>"); - ar1->DrawArrow(5.5,9.2,5.5,8.7,0.012,"|>"); - ar1->DrawArrow(5.5,5,5.5,4.2,0.012,"|>"); - ar1->DrawArrow(8.5,9.2,8.5,8.2,0.012,"|>"); - ar1->DrawArrow(9.5,8.1,9.5,9.0,0.012,"|>"); - ar1->DrawArrow(6.5,19,6.5,17.6,0.012,"|>"); - ar1->DrawArrow(8.5,19,8.5,17.1,0.012,"|>"); - ar1->DrawArrow(11.5,19,11.5,17.1,0.012,"|>"); + ar1.DrawArrow(2.5,17.5,2.5,18.9,0.012,"|>"); + ar1.DrawArrow(5.5,9.2,5.5,8.7,0.012,"|>"); + ar1.DrawArrow(5.5,5,5.5,4.2,0.012,"|>"); + ar1.DrawArrow(8.5,9.2,8.5,8.2,0.012,"|>"); + ar1.DrawArrow(9.5,8.1,9.5,9.0,0.012,"|>"); + ar1.DrawArrow(6.5,19,6.5,17.6,0.012,"|>"); + ar1.DrawArrow(8.5,19,8.5,17.1,0.012,"|>"); + ar1.DrawArrow(11.5,19,11.5,17.1,0.012,"|>"); TPaveLabel *ootitle = new TPaveLabel(10.5,7.8,17,8.8,"Objects Data Base"); diff --git a/tutorials/tree/tree.C b/tutorials/tree/tree.C index 22d603e0f8696..8137330741f24 100644 --- a/tutorials/tree/tree.C +++ b/tutorials/tree/tree.C @@ -106,21 +106,21 @@ void tree() { zipbuffer->AddText("(if compression)"); zipbuffer->SetFillColor(offsetcolor); zipbuffer->Draw(); - TArrow* ar1 = new TArrow(); - ar1->SetLineWidth(2); - ar1->SetLineColor(1); - ar1->SetFillStyle(1001); - ar1->SetFillColor(1); - ar1->DrawArrow(.21,.275,.39,.275,0.015,"|>"); - ar1->DrawArrow(.23,.375,.39,.375,0.015,"|>"); - ar1->DrawArrow(.25,.805,.39,.805,0.015,"|>"); - ar1->DrawArrow(.50,.805,.59,.805,0.015,"|>"); - ar1->DrawArrow(.70,.805,.79,.805,0.015,"|>"); - ar1->DrawArrow(.50,.275,.59,.275,0.015,"|>"); - ar1->DrawArrow(.70,.275,.79,.275,0.015,"|>"); - ar1->DrawArrow(.45,.175,.54,.175,0.015,"|>"); - ar1->DrawArrow(.43,.075,.54,.075,0.015,"|>"); - ar1->DrawArrow(.41,-.025,.54,-.025,0.015,"|>"); + TArrow ar1; + ar1.SetLineWidth(2); + ar1.SetLineColor(1); + ar1.SetFillStyle(1001); + ar1.SetFillColor(1); + ar1.DrawArrow(.21,.275,.39,.275,0.015,"|>"); + ar1.DrawArrow(.23,.375,.39,.375,0.015,"|>"); + ar1.DrawArrow(.25,.805,.39,.805,0.015,"|>"); + ar1.DrawArrow(.50,.805,.59,.805,0.015,"|>"); + ar1.DrawArrow(.70,.805,.79,.805,0.015,"|>"); + ar1.DrawArrow(.50,.275,.59,.275,0.015,"|>"); + ar1.DrawArrow(.70,.275,.79,.275,0.015,"|>"); + ar1.DrawArrow(.45,.175,.54,.175,0.015,"|>"); + ar1.DrawArrow(.43,.075,.54,.075,0.015,"|>"); + ar1.DrawArrow(.41,-.025,.54,-.025,0.015,"|>"); TLine* ldot = new TLine(.95,.92,.99,.92); ldot->SetLineStyle(3); ldot->Draw(); From afa57c52a26d7322c10324ec8536165a7f9757dc Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 10:20:49 +0200 Subject: [PATCH 085/104] Fix TMarker::DrawMarker memory leaks in spectrum tutorials --- tutorials/spectrum/Src.C | 8 ++++---- tutorials/spectrum/Src2.C | 8 ++++---- tutorials/spectrum/Src3.C | 8 ++++---- tutorials/spectrum/Src4.C | 8 ++++---- tutorials/spectrum/Src5.C | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tutorials/spectrum/Src.C b/tutorials/spectrum/Src.C index 28ce8660b3eeb..fcf44e053ae3f 100644 --- a/tutorials/spectrum/Src.C +++ b/tutorials/spectrum/Src.C @@ -41,12 +41,12 @@ void Src() { Double_t *PositionX = s->GetPositionX(); Double_t *PositionY = s->GetPositionY(); search->Draw("COL"); - auto m = new TMarker(); - m->SetMarkerStyle(23); - m->SetMarkerColor(kRed); + TMarker m; + m.SetMarkerStyle(23); + m.SetMarkerColor(kRed); for (i=0;iDrawMarker(PositionX[i],PositionY[i]); + m.DrawMarker(PositionX[i],PositionY[i]); } } diff --git a/tutorials/spectrum/Src2.C b/tutorials/spectrum/Src2.C index 044202a75df72..a97e7193c9b7a 100644 --- a/tutorials/spectrum/Src2.C +++ b/tutorials/spectrum/Src2.C @@ -41,12 +41,12 @@ void Src2() { Double_t *PositionX = s->GetPositionX(); Double_t *PositionY = s->GetPositionY(); search->Draw("COL"); - auto m = new TMarker(); - m->SetMarkerStyle(23); - m->SetMarkerColor(kRed); + TMarker m; + m.SetMarkerStyle(23); + m.SetMarkerColor(kRed); for (i=0;iDrawMarker(PositionX[i],PositionY[i]); + m.DrawMarker(PositionX[i],PositionY[i]); } } diff --git a/tutorials/spectrum/Src3.C b/tutorials/spectrum/Src3.C index 72ae67a85e57c..3893f841dc4be 100644 --- a/tutorials/spectrum/Src3.C +++ b/tutorials/spectrum/Src3.C @@ -41,12 +41,12 @@ void Src3() { Double_t *PositionX = s->GetPositionX(); Double_t *PositionY = s->GetPositionY(); search->Draw("CONT"); - auto m = new TMarker(); - m->SetMarkerStyle(23); - m->SetMarkerColor(kRed); + TMarker m; + m.SetMarkerStyle(23); + m.SetMarkerColor(kRed); for (i=0;iDrawMarker(PositionX[i],PositionY[i]); + m.DrawMarker(PositionX[i],PositionY[i]); } } diff --git a/tutorials/spectrum/Src4.C b/tutorials/spectrum/Src4.C index 1d3f22e9cad55..efb520c9c2e2e 100644 --- a/tutorials/spectrum/Src4.C +++ b/tutorials/spectrum/Src4.C @@ -41,12 +41,12 @@ void Src4() { Double_t *PositionX = s->GetPositionX(); Double_t *PositionY = s->GetPositionY(); search->Draw("CONT"); - auto m = new TMarker(); - m->SetMarkerStyle(23); - m->SetMarkerColor(kRed); + TMarker m; + m.SetMarkerStyle(23); + m.SetMarkerColor(kRed); for (i=0;iDrawMarker(PositionX[i],PositionY[i]); + m.DrawMarker(PositionX[i],PositionY[i]); } } diff --git a/tutorials/spectrum/Src5.C b/tutorials/spectrum/Src5.C index 87b60c20a8631..3920575a3caae 100644 --- a/tutorials/spectrum/Src5.C +++ b/tutorials/spectrum/Src5.C @@ -41,12 +41,12 @@ void Src5() { Double_t *PositionX = s->GetPositionX(); Double_t *PositionY = s->GetPositionY(); search->Draw("COL"); - auto m = new TMarker(); - m->SetMarkerStyle(23); - m->SetMarkerColor(kRed); + TMarker m; + m.SetMarkerStyle(23); + m.SetMarkerColor(kRed); for (i=0;iDrawMarker(PositionX[i],PositionY[i]); + m.DrawMarker(PositionX[i],PositionY[i]); } } From b911b0b4523ea84427f139a1f46e1d5a76f2a509 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 10:38:23 +0200 Subject: [PATCH 086/104] Release memory and dynamic objects in TSpectrum2 tutorials It is good practice to cleanup memory at macro exit --- tutorials/spectrum/Src.C | 56 ++++++++++++++++++------------------- tutorials/spectrum/Src2.C | 55 ++++++++++++++++++------------------- tutorials/spectrum/Src3.C | 56 ++++++++++++++++++------------------- tutorials/spectrum/Src4.C | 58 +++++++++++++++++++-------------------- tutorials/spectrum/Src5.C | 57 +++++++++++++++++++------------------- 5 files changed, 141 insertions(+), 141 deletions(-) diff --git a/tutorials/spectrum/Src.C b/tutorials/spectrum/Src.C index fcf44e053ae3f..f0d3a041ffcd8 100644 --- a/tutorials/spectrum/Src.C +++ b/tutorials/spectrum/Src.C @@ -11,42 +11,42 @@ #include -void Src() { - Int_t i, j, nfound; +void Src() +{ const Int_t nbinsx = 64; const Int_t nbinsy = 64; - Double_t xmin = 0; - Double_t xmax = (Double_t)nbinsx; - Double_t ymin = 0; - Double_t ymax = (Double_t)nbinsy; - Double_t** source = new Double_t*[nbinsx]; - for (i=0;iGetTutorialDir(); - TString file = dir+"/spectrum/TSpectrum2.root"; - TFile *f = new TFile(file.Data()); + std::vector source(nbinsx), dest(nbinsx); + for (Int_t i = 0; i < nbinsx; i++) { + source[i] = new Double_t[nbinsy]; + dest[i] = new Double_t[nbinsy]; + } + TString dir = gROOT->GetTutorialDir(); + TString file = dir + "/spectrum/TSpectrum2.root"; + TFile *f = TFile::Open(file.Data()); gStyle->SetOptStat(0); - auto search = (TH2F*) f->Get("search4"); - auto *s = new TSpectrum2(); - for (i = 0; i < nbinsx; i++){ - for (j = 0; j < nbinsy; j++){ - source[i][j] = search->GetBinContent(i + 1,j + 1); + auto search = (TH2F *)f->Get("search4"); + TSpectrum2 s; + for (Int_t i = 0; i < nbinsx; i++) { + for (Int_t j = 0; j < nbinsy; j++) { + source[i][j] = search->GetBinContent(i + 1, j + 1); } } - nfound = s->SearchHighRes(source, dest, nbinsx, nbinsy, 2, 5, kTRUE, 3, kFALSE, 3); - printf("Found %d candidate peaks\n",nfound); - Double_t *PositionX = s->GetPositionX(); - Double_t *PositionY = s->GetPositionY(); + Int_t nfound = s.SearchHighRes(source.data(), dest.data(), nbinsx, nbinsy, 2, 5, kTRUE, 3, kFALSE, 3); + printf("Found %d candidate peaks\n", nfound); + Double_t *PositionX = s.GetPositionX(); + Double_t *PositionY = s.GetPositionY(); search->Draw("COL"); TMarker m; m.SetMarkerStyle(23); m.SetMarkerColor(kRed); - for (i=0;i -void Src2() { - Int_t i, j, nfound; +void Src2() +{ const Int_t nbinsx = 256; const Int_t nbinsy = 256; - Double_t xmin = 0; - Double_t xmax = (Double_t)nbinsx; - Double_t ymin = 0; - Double_t ymax = (Double_t)nbinsy; - Double_t** source = new Double_t*[nbinsx]; - for (i=0;iGetTutorialDir(); - TString file = dir+"/spectrum/TSpectrum2.root"; - TFile *f = new TFile(file.Data()); + std::vector source(nbinsx), dest(nbinsx); + for (Int_t i = 0; i < nbinsx; i++) { + source[i] = new Double_t[nbinsy]; + dest[i] = new Double_t[nbinsy]; + } + TString dir = gROOT->GetTutorialDir(); + TString file = dir + "/spectrum/TSpectrum2.root"; + TFile *f = TFile::Open(file.Data()); gStyle->SetOptStat(0); - auto search = (TH2F*) f->Get("back3"); - auto s = new TSpectrum2(); - for (i = 0; i < nbinsx; i++){ - for (j = 0; j < nbinsy; j++){ - source[i][j] = search->GetBinContent(i + 1,j + 1); + auto search = (TH2F *)f->Get("back3"); + TSpectrum2 s; + for (Int_t i = 0; i < nbinsx; i++) { + for (Int_t j = 0; j < nbinsy; j++) { + source[i][j] = search->GetBinContent(i + 1, j + 1); } } - nfound = s->SearchHighRes(source, dest, nbinsx, nbinsy, 2, 10, kTRUE, 10, kFALSE, 3); - printf("Found %d candidate peaks\n",nfound); - Double_t *PositionX = s->GetPositionX(); - Double_t *PositionY = s->GetPositionY(); + Int_t nfound = s.SearchHighRes(source.data(), dest.data(), nbinsx, nbinsy, 2, 10, kTRUE, 10, kFALSE, 3); + printf("Found %d candidate peaks\n", nfound); + Double_t *PositionX = s.GetPositionX(); + Double_t *PositionY = s.GetPositionY(); search->Draw("COL"); TMarker m; m.SetMarkerStyle(23); m.SetMarkerColor(kRed); - for (i=0;i -void Src3() { - Int_t i, j, nfound; +void Src3() +{ const Int_t nbinsx = 64; const Int_t nbinsy = 64; - Double_t xmin = 0; - Double_t xmax = (Double_t)nbinsx; - Double_t ymin = 0; - Double_t ymax = (Double_t)nbinsy; - Double_t** source = new Double_t*[nbinsx]; - for (i=0;iGetTutorialDir(); - TString file = dir+"/spectrum/TSpectrum2.root"; - TFile *f = new TFile(file.Data()); + std::vector source(nbinsx), dest(nbinsx); + for (Int_t i = 0; i < nbinsx; i++) { + source[i] = new Double_t[nbinsy]; + dest[i] = new Double_t[nbinsy]; + } + TString dir = gROOT->GetTutorialDir(); + TString file = dir + "/spectrum/TSpectrum2.root"; + TFile *f = TFile::Open(file.Data()); gStyle->SetOptStat(0); - auto search = (TH2F*) f->Get("search1"); - auto s = new TSpectrum2(); - for (i = 0; i < nbinsx; i++){ - for (j = 0; j < nbinsy; j++){ - source[i][j] = search->GetBinContent(i + 1,j + 1); + auto search = (TH2F *)f->Get("search1"); + TSpectrum2 s; + for (Int_t i = 0; i < nbinsx; i++) { + for (Int_t j = 0; j < nbinsy; j++) { + source[i][j] = search->GetBinContent(i + 1, j + 1); } } - nfound = s->SearchHighRes(source, dest, nbinsx, nbinsy, 2, 2, kFALSE, 3, kFALSE, 1);//3, 10, 100 - printf("Found %d candidate peaks\n",nfound); - Double_t *PositionX = s->GetPositionX(); - Double_t *PositionY = s->GetPositionY(); + Int_t nfound = s.SearchHighRes(source.data(), dest.data(), nbinsx, nbinsy, 2, 2, kFALSE, 3, kFALSE, 1); // 3, 10, 100 + printf("Found %d candidate peaks\n", nfound); + Double_t *PositionX = s.GetPositionX(); + Double_t *PositionY = s.GetPositionY(); search->Draw("CONT"); TMarker m; m.SetMarkerStyle(23); m.SetMarkerColor(kRed); - for (i=0;i -void Src4() { - Int_t i, j, nfound; +void Src4() +{ const Int_t nbinsx = 64; const Int_t nbinsy = 64; - Double_t xmin = 0; - Double_t xmax = (Double_t)nbinsx; - Double_t ymin = 0; - Double_t ymax = (Double_t)nbinsy; - Double_t** source = new Double_t*[nbinsx]; - for (i=0;iGetTutorialDir(); - TString file = dir+"/spectrum/TSpectrum2.root"; - TFile *f = new TFile(file.Data()); + std::vector source(nbinsx), dest(nbinsx); + for (Int_t i = 0; i < nbinsx; i++) { + source[i] = new Double_t[nbinsy]; + dest[i] = new Double_t[nbinsy]; + } + TString dir = gROOT->GetTutorialDir(); + TString file = dir + "/spectrum/TSpectrum2.root"; + TFile *f = TFile::Open(file.Data()); gStyle->SetOptStat(0); - auto search = (TH2F*) f->Get("search2"); - auto s = new TSpectrum2(); - for (i = 0; i < nbinsx; i++){ - for (j = 0; j < nbinsy; j++){ - source[i][j] = search->GetBinContent(i + 1,j + 1); + auto search = (TH2F *)f->Get("search2"); + TSpectrum2 s; + for (Int_t i = 0; i < nbinsx; i++) { + for (Int_t j = 0; j < nbinsy; j++) { + source[i][j] = search->GetBinContent(i + 1, j + 1); } - } - nfound = s->SearchHighRes(source, dest, nbinsx, nbinsy, 3, 5, kFALSE, 10, kTRUE, 3); - printf("Found %d candidate peaks\n",nfound); - Double_t *PositionX = s->GetPositionX(); - Double_t *PositionY = s->GetPositionY(); + } + Int_t nfound = s.SearchHighRes(source.data(), dest.data(), nbinsx, nbinsy, 3, 5, kFALSE, 10, kTRUE, 3); + printf("Found %d candidate peaks\n", nfound); + Double_t *PositionX = s.GetPositionX(); + Double_t *PositionY = s.GetPositionY(); search->Draw("CONT"); TMarker m; m.SetMarkerStyle(23); m.SetMarkerColor(kRed); - for (i=0;i -void Src5() { - Int_t i, j, nfound; +void Src5() +{ const Int_t nbinsx = 64; const Int_t nbinsy = 64; - Double_t xmin = 0; - Double_t xmax = (Double_t)nbinsx; - Double_t ymin = 0; - Double_t ymax = (Double_t)nbinsy; - Double_t** source = new Double_t*[nbinsx]; - for (i=0;iGetTutorialDir(); - TString file = dir+"/spectrum/TSpectrum2.root"; - TFile *f = new TFile(file.Data()); + std::vector source(nbinsx), dest(nbinsx); + for (Int_t i = 0; i < nbinsx; i++) { + source[i] = new Double_t[nbinsy]; + dest[i] = new Double_t[nbinsy]; + } + TString dir = gROOT->GetTutorialDir(); + TString file = dir + "/spectrum/TSpectrum2.root"; + TFile *f = TFile::Open(file.Data()); gStyle->SetOptStat(0); - auto search = (TH2F*) f->Get("search3;1"); - TSpectrum2 *s = new TSpectrum2(); - for (i = 0; i < nbinsx; i++){ - for (j = 0; j < nbinsy; j++){ - source[i][j] = search->GetBinContent(i + 1,j + 1); + auto search = (TH2F *)f->Get("search3;1"); + TSpectrum2 s; + for (Int_t i = 0; i < nbinsx; i++) { + for (Int_t j = 0; j < nbinsy; j++) { + source[i][j] = search->GetBinContent(i + 1, j + 1); } } - nfound = s->SearchHighRes(source, dest, nbinsx, nbinsy, 2, 5, kFALSE, 10, kFALSE, 1); - printf("Found %d candidate peaks\n",nfound); - Double_t *PositionX = s->GetPositionX(); - Double_t *PositionY = s->GetPositionY(); + Int_t nfound = s.SearchHighRes(source.data(), dest.data(), nbinsx, nbinsy, 2, 5, kFALSE, 10, kFALSE, 1); + printf("Found %d candidate peaks\n", nfound); + Double_t *PositionX = s.GetPositionX(); + Double_t *PositionY = s.GetPositionY(); search->Draw("COL"); TMarker m; m.SetMarkerStyle(23); m.SetMarkerColor(kRed); - for (i=0;i Date: Wed, 29 Jun 2022 10:41:19 +0200 Subject: [PATCH 087/104] Fix TArc::DrawArc related leaks --- test/stressGraphics.cxx | 18 +++++++++--------- tutorials/graphs/waves.C | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/test/stressGraphics.cxx b/test/stressGraphics.cxx index 9db999f7de4a8..505a6fc1e0372 100644 --- a/test/stressGraphics.cxx +++ b/test/stressGraphics.cxx @@ -2977,19 +2977,19 @@ void waves() finter->SetContour(colNum-2); finter->Draw("samecolorz"); - TArc *arc = new TArc();; - arc->SetFillStyle(0); - arc->SetLineWidth(2); - arc->SetLineColor(5); + TArc arc; + arc.SetFillStyle(0); + arc.SetLineWidth(2); + arc.SetLineColor(5); Float_t r = 0.5 * lambda, dr = lambda; - for (Int_t i = 0; i < 15; i++) { - arc->DrawArc(0, 0.5*d, r, 0., 360., "only"); - arc->DrawArc(0, -0.5*d, r, 0., 360., "only"); + for (Int_t i = 0; i < 15; i++) { + arc.DrawArc(0, 0.5*d, r, 0., 360., "only"); + arc.DrawArc(0, -0.5*d, r, 0., 360., "only"); r += dr; } - pad ->cd(); - TF2 * fresult = new TF2("result",result, 14, 15, -10, 10, 4); + pad->cd(); + TF2 *fresult = new TF2("result",result, 14, 15, -10, 10, 4); fresult->SetParameters(amp, lambda, d, 1); fresult->SetNpx(300); diff --git a/tutorials/graphs/waves.C b/tutorials/graphs/waves.C index d2acd5524a62d..26dfd095bcebc 100644 --- a/tutorials/graphs/waves.C +++ b/tutorials/graphs/waves.C @@ -122,14 +122,14 @@ void waves( Double_t d = 3, Double_t lambda = 1, Double_t amp = 10) finter->SetContour(colNum-2); finter->Draw("samecol"); - TArc *arc = new TArc();; - arc->SetFillStyle(0); - arc->SetLineWidth(2); - arc->SetLineColor(5); + TArc arc; + arc.SetFillStyle(0); + arc.SetLineWidth(2); + arc.SetLineColor(5); Float_t r = 0.5 * lambda, dr = lambda; for (Int_t i = 0; i < 16; i++) { - arc->DrawArc(0, 0.5*d, r, 0., 360., "only"); - arc->DrawArc(0, -0.5*d, r, 0., 360., "only"); + arc.DrawArc(0, 0.5*d, r, 0., 360., "only"); + arc.DrawArc(0, -0.5*d, r, 0., 360., "only"); r += dr; } From 4a4b27bcbb3c134e0657e0d23db73110dd349b2a Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 10:50:30 +0200 Subject: [PATCH 088/104] Fix leak TPaveLabel::DrawPaveLabel usage Original object was not deleted properly --- tutorials/hist/draw2dopt.C | 36 ++++++++++++++++++------------------ tutorials/io/file.C | 4 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tutorials/hist/draw2dopt.C b/tutorials/hist/draw2dopt.C index 035a918a98c23..82c22e91ba710 100644 --- a/tutorials/hist/draw2dopt.C +++ b/tutorials/hist/draw2dopt.C @@ -19,7 +19,7 @@ void draw2dopt() auto h2 = new TH2F("h2","xygaus + xygaus(5) + xylandau(10)",20,-4,4,20,-4,4); h2->SetFillColor(46); h2->FillRandom("f2",40000); - auto pl = new TPaveLabel(); + TPaveLabel pl; //basic 2-d options Float_t xMin=0.67, yMin=0.875, xMax=0.85, yMax=0.95; @@ -28,13 +28,13 @@ void draw2dopt() c2h->Divide(2,2); c2h->SetFillColor(cancolor); c2h->cd(1); - h2->Draw(); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"SCAT","brNDC"); + h2->Draw(); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"SCAT","brNDC"); c2h->cd(2); - h2->Draw("box"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"BOX","brNDC"); + h2->Draw("box"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"BOX","brNDC"); c2h->cd(3); - h2->Draw("arr"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"ARR","brNDC"); + h2->Draw("arr"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"ARR","brNDC"); c2h->cd(4); - h2->Draw("colz"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"COLZ","brNDC"); + h2->Draw("colz"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"COLZ","brNDC"); c2h->Update(); //text option @@ -42,7 +42,7 @@ void draw2dopt() gPad->SetGrid(); ctext->SetFillColor(cancolor); ctext->SetGrid(); - h2->Draw("text"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"TEXT","brNDC"); + h2->Draw("text"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"TEXT","brNDC"); ctext->Update(); //contour options @@ -51,16 +51,16 @@ void draw2dopt() gPad->SetGrid(); cont->SetFillColor(cancolor); cont->cd(1); - h2->Draw("contz"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"CONTZ","brNDC"); + h2->Draw("contz"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"CONTZ","brNDC"); cont->cd(2); gPad->SetGrid(); - h2->Draw("cont1"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"CONT1","brNDC"); + h2->Draw("cont1"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"CONT1","brNDC"); cont->cd(3); gPad->SetGrid(); - h2->Draw("cont2"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"CONT2","brNDC"); + h2->Draw("cont2"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"CONT2","brNDC"); cont->cd(4); gPad->SetGrid(); - h2->Draw("cont3"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"CONT3","brNDC"); + h2->Draw("cont3"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"CONT3","brNDC"); cont->Update(); //lego options @@ -68,15 +68,15 @@ void draw2dopt() lego->Divide(2,2); lego->SetFillColor(cancolor); lego->cd(1); - h2->Draw("lego"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"LEGO","brNDC"); + h2->Draw("lego"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"LEGO","brNDC"); lego->cd(2); - h2->Draw("lego1"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"LEGO1","brNDC"); + h2->Draw("lego1"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"LEGO1","brNDC"); lego->cd(3); gPad->SetTheta(61); gPad->SetPhi(-82); - h2->Draw("surf1pol"); pl->DrawPaveLabel(xMin,yMin,xMax+0.05,yMax,"SURF1POL","brNDC"); + h2->Draw("surf1pol"); pl.DrawPaveLabel(xMin,yMin,xMax+0.05,yMax,"SURF1POL","brNDC"); lego->cd(4); gPad->SetTheta(21); gPad->SetPhi(-90); - h2->Draw("surf1cyl"); pl->DrawPaveLabel(xMin,yMin,xMax+0.05,yMax,"SURF1CYL","brNDC"); + h2->Draw("surf1cyl"); pl.DrawPaveLabel(xMin,yMin,xMax+0.05,yMax,"SURF1CYL","brNDC"); lego->Update(); //surface options @@ -84,12 +84,12 @@ void draw2dopt() surf->Divide(2,2); surf->SetFillColor(cancolor); surf->cd(1); - h2->Draw("surf1"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"SURF1","brNDC"); + h2->Draw("surf1"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"SURF1","brNDC"); surf->cd(2); - h2->Draw("surf2z"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"SURF2Z","brNDC"); + h2->Draw("surf2z"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"SURF2Z","brNDC"); surf->cd(3); - h2->Draw("surf3"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"SURF3","brNDC"); + h2->Draw("surf3"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"SURF3","brNDC"); surf->cd(4); - h2->Draw("surf4"); pl->DrawPaveLabel(xMin,yMin,xMax,yMax,"SURF4","brNDC"); + h2->Draw("surf4"); pl.DrawPaveLabel(xMin,yMin,xMax,yMax,"SURF4","brNDC"); surf->Update(); } diff --git a/tutorials/io/file.C b/tutorials/io/file.C index daf9f7223071d..9367ef8161ea9 100644 --- a/tutorials/io/file.C +++ b/tutorials/io/file.C @@ -17,7 +17,7 @@ void file(){ title->SetFillColor(16); title->Draw(); - // horizonthal file layout + // horizontal file layout TPave *file = new TPave(1,8.5,20,11); file->SetFillColor(11); file->Draw(); @@ -109,7 +109,7 @@ void file(){ TPaveText *lrecord = new TPaveText(10,0.2,19.5,6.5); lrecord->SetFillColor(33); lrecord->Draw(); - TText *tlrh=lrecord->AddText("Logical Record Header (TKEY)"); + TText *tlrh = lrecord->AddText("Logical Record Header (TKEY)"); tlrh->SetTextAlign(22); tlrh->SetTextSize(0.04); lrecord->SetTextSize(0.027); From d18d368cfad53f546935d4d3cb825a5f72ff6c0f Mon Sep 17 00:00:00 2001 From: Vincenzo Eduardo Padulano Date: Tue, 28 Jun 2022 13:21:12 +0200 Subject: [PATCH 089/104] [tree] Add interface to add a friend in RFriendInfo --- tree/tree/inc/ROOT/InternalTreeUtils.hxx | 8 ++++ tree/tree/src/InternalTreeUtils.cxx | 55 ++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/tree/tree/inc/ROOT/InternalTreeUtils.hxx b/tree/tree/inc/ROOT/InternalTreeUtils.hxx index d766000c7af08..033fcf2902f4d 100644 --- a/tree/tree/inc/ROOT/InternalTreeUtils.hxx +++ b/tree/tree/inc/ROOT/InternalTreeUtils.hxx @@ -59,6 +59,14 @@ struct RFriendInfo { vector with a single empty string. */ std::vector> fFriendChainSubNames; + + void AddFriend(const std::string &treeName, const std::string &fileNameGlob, const std::string &alias = ""); + + void + AddFriend(const std::string &treeName, const std::vector &fileNameGlobs, const std::string &alias = ""); + + void AddFriend(const std::vector> &treeAndFileNameGlobs, + const std::string &alias = ""); }; std::vector GetFileNamesFromTree(const TTree &tree); diff --git a/tree/tree/src/InternalTreeUtils.cxx b/tree/tree/src/InternalTreeUtils.cxx index 5f75d83620b84..f68f96f730fbc 100644 --- a/tree/tree/src/InternalTreeUtils.cxx +++ b/tree/tree/src/InternalTreeUtils.cxx @@ -23,6 +23,61 @@ namespace ROOT { namespace Internal { namespace TreeUtils { +//////////////////////////////////////////////////////////////////////////////// +/// \brief Add information of a single friend. +/// +/// \param[in] treeName Name of the tree. +/// \param[in] fileNameGlob Path to the file. Refer to TChain::Add for globbing rules. +/// \param[in] alias Alias for this friend. +void RFriendInfo::AddFriend(const std::string &treeName, const std::string &fileNameGlob, const std::string &alias) +{ + fFriendNames.emplace_back(std::make_pair(treeName, alias)); + fFriendFileNames.emplace_back(std::vector{fileNameGlob}); + fFriendChainSubNames.emplace_back(); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief Add information of a single friend. +/// +/// \param[in] treeName Name of the tree. +/// \param[in] fileNameGlobs Paths to the files. Refer to TChain::Add for globbing rules. +/// \param[in] alias Alias for this friend. +void RFriendInfo::AddFriend(const std::string &treeName, const std::vector &fileNameGlobs, + const std::string &alias) +{ + fFriendNames.emplace_back(std::make_pair(treeName, alias)); + fFriendFileNames.emplace_back(fileNameGlobs); + fFriendChainSubNames.emplace_back(std::vector(fileNameGlobs.size(), treeName)); +} + +//////////////////////////////////////////////////////////////////////////////// +/// \brief Add information of a single friend. +/// +/// \param[in] treeAndFileNameGlobs Pairs of (treename, filename). Refer to TChain::Add for globbing rules. +/// \param[in] alias Alias for this friend. +void RFriendInfo::AddFriend(const std::vector> &treeAndFileNameGlobs, + const std::string &alias) +{ + fFriendNames.emplace_back(std::make_pair("", alias)); + + fFriendFileNames.emplace_back(); + fFriendChainSubNames.emplace_back(); + + auto &theseFileNames = fFriendFileNames.back(); + auto &theseChainSubNames = fFriendChainSubNames.back(); + auto nPairs = treeAndFileNameGlobs.size(); + theseFileNames.reserve(nPairs); + theseChainSubNames.reserve(nPairs); + + auto fSubNamesIt = std::back_inserter(theseFileNames); + auto fNamesIt = std::back_inserter(theseChainSubNames); + + for (const auto &names : treeAndFileNameGlobs) { + *fSubNamesIt = names.first; + *fNamesIt = names.second; + } +} + //////////////////////////////////////////////////////////////////////////////// /// \fn std::vector GetFileNamesFromTree(const TTree &tree) /// \ingroup tree From 3febf4ab2bd1cc675aacabd8e4023c9a6eed1825 Mon Sep 17 00:00:00 2001 From: Vincenzo Eduardo Padulano Date: Tue, 28 Jun 2022 13:21:39 +0200 Subject: [PATCH 090/104] [tree][NFC] Clarify comment --- tree/tree/inc/ROOT/InternalTreeUtils.hxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tree/tree/inc/ROOT/InternalTreeUtils.hxx b/tree/tree/inc/ROOT/InternalTreeUtils.hxx index 033fcf2902f4d..14892f05981e4 100644 --- a/tree/tree/inc/ROOT/InternalTreeUtils.hxx +++ b/tree/tree/inc/ROOT/InternalTreeUtils.hxx @@ -55,8 +55,8 @@ struct RFriendInfo { Names of the subtrees of a friend TChain. fFriendChainSubNames[i] is the list of names of the trees that make a friend TChain whose information is stored at fFriendNames[i] and fFriendFileNames[i]. If instead the friend - tree at position `i` is a TTree, fFriendChainSubNames[i] will be just a - vector with a single empty string. + tree at position `i` is a TTree, fFriendChainSubNames[i] will be an empty + vector. */ std::vector> fFriendChainSubNames; From ed6f3bf37de20e578b247976239672dbb6ca9377 Mon Sep 17 00:00:00 2001 From: Vincenzo Eduardo Padulano Date: Tue, 28 Jun 2022 13:24:57 +0200 Subject: [PATCH 091/104] [tree][NFC] make formatter happy --- tree/tree/src/InternalTreeUtils.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tree/tree/src/InternalTreeUtils.cxx b/tree/tree/src/InternalTreeUtils.cxx index f68f96f730fbc..04a618b28fedb 100644 --- a/tree/tree/src/InternalTreeUtils.cxx +++ b/tree/tree/src/InternalTreeUtils.cxx @@ -268,7 +268,7 @@ std::vector GetTreeFullPaths(const TTree &tree) if (dynamic_cast(treeDir)) { return {tree.GetName()}; } - std::string fullPath = treeDir->GetPath(); // e.g. "file.root:/dir" + std::string fullPath = treeDir->GetPath(); // e.g. "file.root:/dir" fullPath = fullPath.substr(fullPath.rfind(":/") + 1); // e.g. "/dir" fullPath += "/"; fullPath += tree.GetName(); // e.g. "/dir/tree" From ea09711cb4f0b29f7cee44091eb90fded03553f2 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Mon, 11 Apr 2022 18:13:32 +0200 Subject: [PATCH 092/104] Using higher-level wrapper of OpenSSL SHA1 hash function in civetweb This is to get rid of deprecation warninigs when building on Ubuntu 22.04. Should cause no backwards compatibility poblems, as the functions that are used now are around at least since OpenSSL 1.0.2: https://www.openssl.org/docs/man1.0.2/man3/EVP_DigestInit_ex.html This patch was already applied to upstream civet: https://github.com/civetweb/civetweb/pull/1072 --- net/http/civetweb/civetweb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/http/civetweb/civetweb.c b/net/http/civetweb/civetweb.c index fea9e6f98c4ac..89a3f3807b9b9 100644 --- a/net/http/civetweb/civetweb.c +++ b/net/http/civetweb/civetweb.c @@ -12330,7 +12330,6 @@ send_websocket_handshake(struct mg_connection *conn, const char *websock_key) { static const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; char buf[100], sha[20], b64_sha[sizeof(sha) * 2]; - SHA_CTX sha_ctx; int truncated; /* Calculate Sec-WebSocket-Accept reply from Sec-WebSocket-Key. */ @@ -12342,9 +12341,8 @@ send_websocket_handshake(struct mg_connection *conn, const char *websock_key) DEBUG_TRACE("%s", "Send websocket handshake"); - SHA1_Init(&sha_ctx); - SHA1_Update(&sha_ctx, (unsigned char *)buf, (uint32_t)strlen(buf)); - SHA1_Final((unsigned char *)sha, &sha_ctx); + EVP_Digest((unsigned char *)buf, (uint32_t)strlen(buf), (unsigned char *)sha, + NULL, EVP_get_digestbyname("sha1"), NULL); base64_encode((unsigned char *)sha, sizeof(sha), b64_sha); mg_printf(conn, "HTTP/1.1 101 Switching Protocols\r\n" From 08c41c66d88801eac4d05a9464c5139d1406b9d7 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 12:48:20 +0200 Subject: [PATCH 093/104] [civetweb] use EVP_Digest only for OPENSSL 3.0 Keep old code for Windows and older SSL versions --- net/http/civetweb/civetweb.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/net/http/civetweb/civetweb.c b/net/http/civetweb/civetweb.c index 89a3f3807b9b9..7a9dea3d7157e 100644 --- a/net/http/civetweb/civetweb.c +++ b/net/http/civetweb/civetweb.c @@ -12321,15 +12321,20 @@ mg_unlock_context(struct mg_context *ctx) #if defined(USE_WEBSOCKET) #if !defined(NO_SSL_DL) +#if !defined(OPENSSL_API_3_0) #define SHA_API static #include "sha1.inl" #endif +#endif static int send_websocket_handshake(struct mg_connection *conn, const char *websock_key) { static const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; char buf[100], sha[20], b64_sha[sizeof(sha) * 2]; +#if !defined(OPENSSL_API_3_0) + SHA_CTX sha_ctx; +#endif int truncated; /* Calculate Sec-WebSocket-Accept reply from Sec-WebSocket-Key. */ @@ -12341,8 +12346,14 @@ send_websocket_handshake(struct mg_connection *conn, const char *websock_key) DEBUG_TRACE("%s", "Send websocket handshake"); +#if defined(OPENSSL_API_3_0) EVP_Digest((unsigned char *)buf, (uint32_t)strlen(buf), (unsigned char *)sha, NULL, EVP_get_digestbyname("sha1"), NULL); +#else + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, (unsigned char *)buf, (uint32_t)strlen(buf)); + SHA1_Final((unsigned char *)sha, &sha_ctx); +#endif base64_encode((unsigned char *)sha, sizeof(sha), b64_sha); mg_printf(conn, "HTTP/1.1 101 Switching Protocols\r\n" From 7b7983fa8ab9e1a4af98776f7f80bea1f9b2b0b0 Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Wed, 29 Jun 2022 23:00:37 +0530 Subject: [PATCH 094/104] [TMVA][SOFIE] Fixed the implementation of MaxPool ONNX operator for 1d and 3d case (#10768) * Fix the issue related to 1d and 3d MaxPool operators * Update ROperator_Pool.hxx * The issue related to Maxpool for 1d and 3d fixed * Test related to MaxPool 1d added * MaxPool Operator fixed for 1d and 3d cases and tests added * Max Pool operator errors related to 1d and 3d case resolved * Max Pool operator errors related to 1d and 3d case resolved * Updated the Pool Operator * Fix warning in new implementation of Pool operator * Added the tests for MaxPool 2d and 3d Operators * Fix 2d and 3d MaxPool operators Use the correct stride for the height when loopoing at the tensor element. The height stride for 2d is equal to wsize, and in 3d is equal to wsize*dsize. Precompute the hstride in 3d to avoid a multiplication when looping through the tensor elements. * Tests added for AvgPool * Corrected the spelling errors Co-authored-by: moneta --- tmva/sofie/inc/TMVA/ROperator_Pool.hxx | 387 +++++++++++++----- tmva/sofie/test/TestCustomModelsFromONNX.cxx | 137 +++++++ tmva/sofie/test/input_models/AvgPool.onnx | Bin 0 -> 220 bytes tmva/sofie/test/input_models/MaxPool1d.onnx | Bin 0 -> 202 bytes tmva/sofie/test/input_models/MaxPool2d.onnx | Bin 0 -> 218 bytes tmva/sofie/test/input_models/MaxPool3d.onnx | Bin 0 -> 234 bytes .../input_models/references/AvgPool.ref.hxx | 6 + .../input_models/references/MaxPool1d.ref.hxx | 14 + .../input_models/references/MaxPool2d.ref.hxx | 8 + .../input_models/references/MaxPool3d.ref.hxx | 6 + 10 files changed, 455 insertions(+), 103 deletions(-) create mode 100644 tmva/sofie/test/input_models/AvgPool.onnx create mode 100644 tmva/sofie/test/input_models/MaxPool1d.onnx create mode 100644 tmva/sofie/test/input_models/MaxPool2d.onnx create mode 100644 tmva/sofie/test/input_models/MaxPool3d.onnx create mode 100644 tmva/sofie/test/input_models/references/AvgPool.ref.hxx create mode 100644 tmva/sofie/test/input_models/references/MaxPool1d.ref.hxx create mode 100644 tmva/sofie/test/input_models/references/MaxPool2d.ref.hxx create mode 100644 tmva/sofie/test/input_models/references/MaxPool3d.ref.hxx diff --git a/tmva/sofie/inc/TMVA/ROperator_Pool.hxx b/tmva/sofie/inc/TMVA/ROperator_Pool.hxx index ece5b2493a858..5564b63a220b6 100644 --- a/tmva/sofie/inc/TMVA/ROperator_Pool.hxx +++ b/tmva/sofie/inc/TMVA/ROperator_Pool.hxx @@ -17,7 +17,7 @@ namespace Experimental { namespace SOFIE { struct RAttributes_Pool { - // structure containing Pool attributes + // structure that contains Pool attribute std::string auto_pad = "NOTSET"; int ceil_mode = 0; int count_include_pad = 0; // not for MaxPool @@ -55,6 +55,7 @@ private: std::string fType; + size_t fDim; // dimension of the MaxPool bool fUseSession = false; public: @@ -84,97 +85,152 @@ public: // return input type (defined abstract in ROperator class ) std::vector TypeInference(std::vector input) { // only one input in Pool operators - return input; + return input; } - // function returning output shape given input + // function returning output shape given input std::vector> ShapeInference(std::vector> input) { - // shape of pooling input has to be (according to ONNX): N x C x H x W + // shape of pooling input has to be (according to ONNX): NxCxHxW // Where N is batch size, C : input channels, H : input height, W = input width - // or it can be [N, C, F1,F2,....FN] . Minimum dimension is 3 + // or it can be [N, C, F1,F2,....FN] . Minimum dimension is 3 if (input.size() != 1 ) { throw std::runtime_error("TMVA SOFIE" + Name() + "Op Shape inference need 1 input tensor"); } if (input[0].size() < 3) { throw std::runtime_error("TMVA SOFIE" + Name() + "Op Shape inference only accept tensor with at least 3 dimensions"); } - // for the time being support only 4 dimensions - if (input[0].size() != 4) { + // support only input tensors with dim = 3,4,5 + if (input[0].size() < 3 || input[0].size() > 5) { throw std::runtime_error("TMVA SOFIE" + Name() + "Op : tensors with dimension " + std::to_string(input[0].size()) + " are not yet supported"); } - assert(!fAttrKernelShape.empty()); - size_t kHeight = fAttrKernelShape[0]; - size_t kWidth = fAttrKernelShape[1]; + if (input[0].size() -2 != fDim) { + throw + std::runtime_error("TMVA SOFIE Pool Op Shape inference - invalid inputs "); + } + // kernel shape + size_t k1 = ((fAttrKernelShape.empty())? input[0][2] : fAttrKernelShape[0]); + size_t k2 = (fDim > 1) ? ((fAttrKernelShape.empty()) ? input[0][3] : fAttrKernelShape[1]) : 1; + size_t k3 = (fDim > 2) ? ((fAttrKernelShape.empty()) ? input[0][4] : fAttrKernelShape[2]) : 1; + + + size_t i1 = (fDim > 1) ? ((fDim > 2) ? 3 : 2) : 1; + size_t i2 = (fDim > 2) ? 4 : 3; + size_t i3 = 5; if (fAttrDilations.empty()) { - fAttrDilations = {1, 1}; + fAttrDilations = {1, 1, 1}; } - // Shape of the kernel - fAttrKernelShape = {kHeight + (fAttrDilations[0] - 1) * (kHeight - 1), kWidth + (fAttrDilations[1] - 1) * (kWidth - 1)}; + fAttrDilations.resize(3); + if (fDim < 3) { + fAttrDilations.resize(3, 1); + } + // Shape of the kernel + fAttrKernelShape = {k1 + (fAttrDilations[0] - 1) * (k1 - 1), + k2 + (fAttrDilations[1] - 1) * (k2 - 1), + k3 + (fAttrDilations[2] - 1) * (k3 - 1)}; if (fAttrAutopad == "NOTSET") { if (fAttrPads.empty()) { - fAttrPads = {1, 1, 1, 1}; + fAttrPads = {1, 1, 1, 1, 1, 1}; } } else if (fAttrAutopad == "SAME_UPPER" || fAttrAutopad == "SAME_LOWER") { - fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2}; + if (fDim == 1) + fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[0] / 2}; + else if (fDim == 2) + fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2}; + else if (fDim == 3) + fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[2] / 2, + fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[2] / 2}; + // add extra padding at beginning or end (depending if SAME_UPPER or SAME_LOWER) + // need to check this! if (fAttrKernelShape[0] % 2 == 1) { - (fAttrAutopad == "SAME_UPPER") ? fAttrPads[0]++ : fAttrPads[2]++; + (fAttrAutopad == "SAME_UPPER") ? fAttrPads[0]++ : fAttrPads[i1]++; + } + if (fDim > 1 && fAttrKernelShape[1] % 2 == 1) { + (fAttrAutopad == "SAME_UPPER") ? fAttrPads[1]++ : fAttrPads[i2]++; } - if (fAttrKernelShape[1] % 2 == 1) { - (fAttrAutopad == "SAME_UPPER") ? fAttrPads[1]++ : fAttrPads[3]++; + if (fDim > 2 && fAttrKernelShape[2] % 2 == 1) { + (fAttrAutopad == "SAME_UPPER") ? fAttrPads[2]++ : fAttrPads[i3]++; } } else if (fAttrAutopad != "VALID") { throw std::runtime_error("TMVA SOFIE" + Name() + "Op invalid Autopad value : " + fAttrAutopad); } + // to be sure pad is vector of size 6 + if (fDim < 3) fAttrPads.resize(6, 0); if (fAttrStrides.empty()) { - fAttrStrides = {1, 1}; + fAttrStrides = {1, 1, 1}; } - size_t outputHeight = - (input[0][2] + fAttrPads[0] + fAttrPads[2] - fAttrKernelShape[0] + fAttrStrides[0]) / - fAttrStrides[0]; - size_t outputWidth = - (input[0][3] + fAttrPads[1] + fAttrPads[3] - fAttrKernelShape[1] + fAttrStrides[1]) / - fAttrStrides[1]; + if (fDim < 3) + fAttrStrides.resize(3, 1); + + size_t input1 = input[0][2]; + size_t input2 = (fDim > 1) ? input[0][3] : 1; + size_t input3 = (fDim > 2) ? input[0][4] : 1; - // output is N x M x OH x OW - std::vector> ret({{input[0][0], input[0][1], outputHeight, outputWidth}}); + size_t pad1 = fAttrPads[0] + fAttrPads[i1]; + size_t output1 = (input1 + pad1 - fAttrKernelShape[0]) / fAttrStrides[0] + 1; + + size_t batch_size = input[0][0]; // first element in input tensor + size_t output_channels = input[0][1]; // first element in output tensor + + std::vector> ret({{ batch_size, output_channels, output1 }}); + + if (fDim == 1) + return ret; + + size_t pad2 = fAttrPads[1] + fAttrPads[i2]; + size_t output2 = (input2 + pad2 - fAttrKernelShape[1]) / fAttrStrides[1] + 1; + // output is N x C x OH x OW + ret[0].push_back(output2); + if (fDim == 2) + return ret; + + size_t pad3 = fAttrPads[2] + fAttrPads[i3]; + size_t output3 = (input3 + pad3 - fAttrKernelShape[2] ) / fAttrStrides[2] + 1; + + // output is N x C x OH x OW x OD + ret[0].push_back(output3); return ret; } void Initialize(RModel& model) { + + fUseSession = model.UseSession(); + if (!model.CheckIfTensorAlreadyExist(fNX)) { throw - std::runtime_error("TMVA SOFIE Conv op Input Tensor " + fNX + " is not found in model"); + std::runtime_error("TMVA SOFIE Pool op Input Tensor " + fNX + " is not found in model"); } fShapeX = model.GetTensorShape(fNX); - if (fShapeX.size() != 4) { + if (fShapeX.size() < 3 || fShapeX.size() > 5) { + std::cout << fNX << " : " << ConvertShapeToString(fShapeX) << std::endl; throw - std::runtime_error("TMVA SOFIE Conv Op input tensor" + fNX + " is not of 4 dimensions"); + std::runtime_error("TMVA SOFIE Pool Op input data tensor" + fNX + " is not of 3,4 or 5 dimensions"); } - + fDim = fShapeX.size() - 2; // case of GlobalAveragePool. It is a pool case with kernel shape == image shape if (fPoolMode == GlobalAveragePool) { fPoolMode = AveragePool; - fAttrKernelShape.resize(2); + fAttrKernelShape.resize(3); fAttrKernelShape[0] = fShapeX[2]; - fAttrKernelShape[1] = fShapeX[3]; + if (fDim > 1) + fAttrKernelShape[1] = fShapeX[3]; + if (fDim > 2) + fAttrKernelShape[2] = fShapeX[4]; fAttrAutopad = "VALID"; - fAttrPads = {0, 0, 0, 0}; + fAttrPads = {0, 0, 0, 0, 0, 0 }; assert(fAttrStrides.empty()); } // find shape of Y and add it in the list of intermediate tensors fShapeY = ShapeInference({fShapeX})[0]; model.AddIntermediateTensor(fNY, model.GetTensorType(fNX), fShapeY); - fUseSession = model.UseSession(); - // need cmath for INFINITY when using MaxPool - if (fPoolMode == MaxPool) model.AddNeededStdLib("cmath"); + if (fPoolMode == MaxPool) model.AddNeededStdLib("cmath"); } @@ -189,10 +245,20 @@ public: opName = "op_" + opName; std::stringstream out; // input matrix padded with zero - out << "std::vector<" << fType << "> fVec_" << opName << "_xpad = std::vector<" << fType << ">(" - << fShapeX[1] * (fShapeX[2] + fAttrPads[0] + fAttrPads[2]) * - (fShapeX[3] + fAttrPads[1] + fAttrPads[3]) + if(fDim == 1){ + out << "std::vector<" << fType << "> fVec_" << opName << "_xpad = std::vector<" << fType << ">(" + << fShapeX[1] * (fShapeX[2] + fAttrPads[0] + fAttrPads[2]) << ");\n"; + } + else if(fDim == 2){ + out << "std::vector<" << fType << "> fVec_" << opName << "_xpad = std::vector<" << fType << ">(" + << fShapeX[1] * (fShapeX[2] + fAttrPads[0] + fAttrPads[2]) * (fShapeX[3] + fAttrPads[1] + fAttrPads[3]) << ");\n"; + } + else{ //dim is 3D + out << "std::vector<" << fType << "> fVec_" << opName << "_xpad = std::vector<" << fType << ">(" + << fShapeX[1] * (fShapeX[2] + fAttrPads[0] + fAttrPads[2]) * (fShapeX[3] + fAttrPads[1] + fAttrPads[3]) * + (fShapeX[4] + fAttrPads[2] + fAttrPads[4]) << ");\n"; + } return out.str(); } @@ -205,92 +271,207 @@ public: } std::stringstream out; - + out << "\n//---- operator " << Name() << " " << OpName << "\n"; out << "{\n"; // create a new scope to avoid name clash - // vectorize the (dilated)convolution kernels into a matrix - // no need to transpose the matrix - // size_t hstride = fShapeW[3]; - // size_t hstrideDil = fAttrDilations[0] * fAttrKernelShape[1]; // stride dilated in the height - // size_t wstrideDil = fAttrDilations[1]; - // size_t dstride = fShapeW[2] * fShapeW[3]; - // size_t dstrideDil = fAttrKernelShape[0] * fAttrKernelShape[1]; - // size_t kstride = fShapeW[1] * fShapeW[2] * fShapeW[3]; - // size_t kstrideDil = fShapeW[1] * dstrideDil; - - assert(fShapeX[0] == fShapeY[0]); assert(fShapeX[1] == fShapeY[1]); - assert(fAttrPads.size() == 4); - assert(fAttrKernelShape.size() == 2); + assert(fAttrPads.size() == 6); + assert(fAttrKernelShape.size() == 3); // find lower bounds of filtered area int hmin = - fAttrPads[0]; // minimum lower bound value of filter area - int hmax = fShapeX[2] + fAttrPads[1] - fAttrKernelShape[0] +1; // maximum lower bound value + 1 - int wmin = - fAttrPads[2]; // minimum lower bound value of filter area - int wmax = fShapeX[3] + fAttrPads[3] - fAttrKernelShape[1] +1; // maximum lower bound value + 1 + int hmax = fShapeX[2] + fAttrPads[1] - fAttrKernelShape[0] +1; // maximum lower bound value + 1 + int wmin,wmax,dmin,dmax; + + if(fDim >= 2){ + wmin = - fAttrPads[2]; // minimum lower bound value of filter area + wmax = fShapeX[3] + fAttrPads[3] - fAttrKernelShape[1] +1; // maximum lower bound value + 1 + } + else{ + wmin=1; + wmax=1; + } + if(fDim == 3){ + dmin = - fAttrPads[4]; // minimum lower bound value of filter area + dmax = fShapeX[4] + fAttrPads[5] - fAttrKernelShape[2] +1; // maximum lower bound value + 1 + } + else{ + dmin=1; + dmax=1; + } out << SP << "constexpr int hsize = " << fShapeX[2] << ";\n"; - out << SP << "constexpr int wsize = " << fShapeX[3] << ";\n"; out << SP << "constexpr int hmin = " << hmin << ";\n"; out << SP << "constexpr int hmax = " << hmax << ";\n"; - out << SP << "constexpr int wmin = " << wmin << ";\n"; - out << SP << "constexpr int wmax = " << wmax << ";\n"; out << SP << "constexpr int kh = " << fAttrKernelShape[0] << ";\n"; - out << SP << "constexpr int kw = " << fAttrKernelShape[1] << ";\n"; - + if (fDim > 1) { + size_t wsize = fShapeX[3]; + out << SP << "constexpr int wsize = " << wsize << ";\n"; + out << SP << "constexpr int wmin = " << wmin << ";\n"; + out << SP << "constexpr int wmax = " << wmax << ";\n"; + out << SP << "constexpr int kw = " << fAttrKernelShape[1] << ";\n"; + if (fDim > 2) { + size_t dsize = fShapeX[4]; + out << SP << "constexpr int dsize = " << dsize << ";\n"; + out << SP << "constexpr int dwsize = " << dsize*wsize << ";\n"; // hstride + out << SP << "constexpr int dmin = " << dmin << ";\n"; + out << SP << "constexpr int dmax = " << dmax << ";\n"; + out << SP << "constexpr int kd = " << fAttrKernelShape[2] << ";\n"; + } + } + + bool doPadding = false; for ( auto & e : fAttrPads) doPadding |= (e > 0); - // loop on batches and channels - out << SP << "size_t outIndex = 0;\n"; - out << SP << "for (size_t n = 0; n < " << fShapeX[0]*fShapeX[1] << "; n++) {\n"; - out << SP << SP << "size_t inputOffset = n*" << fShapeX[2]*fShapeX[3] << ";\n"; - out << SP << SP << "for (int i = hmin; i < hmax; i+=" << fAttrStrides[0] << ") {\n"; - out << SP << SP << SP << "for (int j = wmin; j < wmax; j+=" << fAttrStrides[1] << ") {\n"; - // loop on elements of filter region to compute maximum - if (fPoolMode == MaxPool) - out << SP << SP << SP << SP << "float value = -INFINITY;\n"; - else if (fPoolMode == AveragePool) { - out << SP << SP << SP << SP << "float value = 0;\n"; - if (fAttrCountIncludePad == 0 && doPadding) - out << SP << SP << SP << SP << "int nsum = 0;\n"; - else // in case we count the pad values in average - out << SP << SP << SP << SP << "constexpr int nsum = kw*kh;\n"; - } - // loop on rows of filtered region - out << SP << SP << SP << SP << "for (int l = i; l < i + kh; l++) {\n"; - out << SP << SP << SP << SP << SP << "if (l < 0 || l >= hsize) continue;\n"; - // loop on columns of filtered region - out << SP << SP << SP << SP << SP << "for (int k = j; k < j + kw; k++) {\n"; - out << SP << SP << SP << SP << SP << SP << "if (k<0 || k>= wsize) continue;\n"; - out << SP << SP << SP << SP << SP << SP << "int index = inputOffset + l*hsize + k;\n"; - if (fPoolMode == MaxPool) { + + if(fDim==1){ + // loop on batches and channels + out << SP << "size_t outIndex = 0;\n"; + out << SP << "for (size_t n = 0; n < " << fShapeX[0]*fShapeX[1] << "; n++) {\n"; + out << SP << SP << "size_t inputOffset = n*" << fShapeX[2] << ";\n"; + out << SP << SP << "for (int i = hmin; i < hmax; i+=" << fAttrStrides[0] << ") {\n"; + // loop on elements of filter region to compute maximum + if (fPoolMode == MaxPool) + out << SP << SP << SP << SP << "float value = -INFINITY;\n"; + else if (fPoolMode == AveragePool) { + out << SP << SP << SP << SP << "float value = 0;\n"; + if (fAttrCountIncludePad == 0 && doPadding) + out << SP << SP << SP << SP << "int nsum = 0;\n"; + else // in case we count the pad values in average + out << SP << SP << SP << SP << "constexpr int nsum = kh;\n"; + } + // loop on rows of filtered region + out << SP << SP << SP << SP << "for (int l = i; l < i + kh; l++) {\n"; + out << SP << SP << SP << SP << SP << "if (l < 0 || l >= hsize) continue;\n"; + out << SP << SP << SP << SP << SP << SP << "int index = inputOffset + l;\n"; + if (fPoolMode == MaxPool) { out << SP << SP << SP << SP << SP << SP << "auto xval = tensor_" << fNX << "[index];\n"; out << SP << SP << SP << SP << SP << SP << "if (xval > value) value = xval;\n"; - } - else if (fPoolMode == AveragePool) { - // compute sum of values - out << SP << SP << SP << SP << SP << SP << "value += tensor_" << fNX << "[index];\n"; - if (fAttrCountIncludePad == 0 && doPadding) - // compute number of elements used for the average - out << SP << SP << SP << SP << SP << SP << "nsum++;\n"; - } - out << SP << SP << SP << SP << SP << "}\n"; - out << SP << SP << SP << SP << "}\n"; // end loop on region elements - if (fPoolMode == AveragePool) { + } + else if (fPoolMode == AveragePool) { + // compute sum of values + out << SP << SP << SP << SP << SP << SP << "value += tensor_" << fNX << "[index];\n"; + if (fAttrCountIncludePad == 0 && doPadding) + // compute number of elements used for the average + out << SP << SP << SP << SP << SP << SP << "nsum++;\n"; + } + out << SP << SP << SP << SP << SP << "}\n"; // end loop on region elements + if (fPoolMode == AveragePool) { // compute average out << SP << SP << SP << SP << "value /= float(nsum);\n"; + } + + out << SP << SP << SP << SP << "tensor_" << fNY << "[outIndex++] = value;\n"; + + out << SP << SP << "}\n"; // end loop on i (image rows) + out << SP << "}\n"; // end loop on c*b + } + else if(fDim==2){ + // loop on batches and channels + out << SP << "size_t outIndex = 0;\n"; + out << SP << "for (size_t n = 0; n < " << fShapeX[0]*fShapeX[1] << "; n++) {\n"; + out << SP << SP << "size_t inputOffset = n*" << fShapeX[2]*fShapeX[3] << ";\n"; + out << SP << SP << "for (int i = hmin; i < hmax; i+=" << fAttrStrides[0] << ") {\n"; + out << SP << SP << SP << "for (int j = wmin; j < wmax; j+=" << fAttrStrides[1] << ") {\n"; + // loop on elements of filter region to compute maximum + if (fPoolMode == MaxPool) + out << SP << SP << SP << SP << "float value = -INFINITY;\n"; + else if (fPoolMode == AveragePool) { + out << SP << SP << SP << SP << "float value = 0;\n"; + if (fAttrCountIncludePad == 0 && doPadding) + out << SP << SP << SP << SP << "int nsum = 0;\n"; + else // in case we count the pad values in average + out << SP << SP << SP << SP << "constexpr int nsum = kw*kh;\n"; + } + // loop on rows of filtered region + out << SP << SP << SP << SP << "for (int l = i; l < i + kh; l++) {\n"; + out << SP << SP << SP << SP << SP << "if (l < 0 || l >= hsize) continue;\n"; + // loop on columns of filtered region + out << SP << SP << SP << SP << SP << "for (int m = j; m < j + kw; m++) {\n"; + out << SP << SP << SP << SP << SP << SP << "if (m < 0 || m >= wsize) continue;\n"; + out << SP << SP << SP << SP << SP << SP << SP << "int index = inputOffset + l*wsize + m;\n"; + if (fPoolMode == MaxPool) { + out << SP << SP << SP << SP << SP << SP << SP << "auto xval = tensor_" << fNX << "[index];\n"; + out << SP << SP << SP << SP << SP << SP << SP << "if (xval > value) value = xval;\n"; + } + else if (fPoolMode == AveragePool) { + // compute sum of values + out << SP << SP << SP << SP << SP << SP << SP << "value += tensor_" << fNX << "[index];\n"; + if (fAttrCountIncludePad == 0 && doPadding) + // compute number of elements used for the average + out << SP << SP << SP << SP << SP << SP << SP << "nsum++;\n"; + } + out << SP << SP << SP << SP << SP << SP << "}\n"; + out << SP << SP << SP << SP << SP << "}\n"; // end loop on region elements + if (fPoolMode == AveragePool) { + // compute average + out << SP << SP << SP << SP << "value /= float(nsum);\n"; + } + out << SP << SP << SP << SP << "tensor_" << fNY << "[outIndex++] = value;\n"; + out << SP << SP << SP << "}\n"; // end loop on j (columns of image) + out << SP << SP << "}\n"; // end loop on i (image rows) + out << SP << "}\n"; // end loop on c*b } + else if(fDim==3){ + // loop on batches and channels + out << SP << "size_t outIndex = 0;\n"; + out << SP << "for (size_t n = 0; n < " << fShapeX[0]*fShapeX[1] << "; n++) {\n"; + out << SP << SP << "size_t inputOffset = n*" << fShapeX[2]*fShapeX[3]*fShapeX[4] << ";\n"; + out << SP << SP << "for (int i = hmin; i < hmax; i+=" << fAttrStrides[0] << ") {\n"; + out << SP << SP << SP << "for (int j = wmin; j < wmax; j+=" << fAttrStrides[1] << ") {\n"; + out << SP << SP << SP << SP << "for (int k = dmin; k < dmax; k+=" << fAttrStrides[2] << ") {\n"; + // loop on elements of filter region to compute maximum + if (fPoolMode == MaxPool) + out << SP << SP << SP << SP << "float value = -INFINITY;\n"; + else if (fPoolMode == AveragePool) { + out << SP << SP << SP << SP << "float value = 0;\n"; + if (fAttrCountIncludePad == 0 && doPadding) + out << SP << SP << SP << SP << "int nsum = 0;\n"; + else // in case we count the pad values in average + out << SP << SP << SP << SP << "constexpr int nsum = kw*kh*kd;\n"; + } + // loop on rows of filtered region + out << SP << SP << SP << SP << "for (int l = i; l < i + kh; l++) {\n"; + out << SP << SP << SP << SP << SP << "if (l < 0 || l >= hsize) continue;\n"; + // loop on columns of filtered region + out << SP << SP << SP << SP << SP << "for (int m = j; m < j + kw; m++) {\n"; + out << SP << SP << SP << SP << SP << SP << "if (m < 0 || m >= wsize) continue;\n"; + // loop on layers of filtered region + out << SP << SP << SP << SP << SP << SP << "for (int p = k; p < k + kd; p++) {\n"; + out << SP << SP << SP << SP << SP << SP << SP << "if (p < 0 || p >= dsize) continue;\n"; + out << SP << SP << SP << SP << SP << SP << SP << SP << "int index = inputOffset + l*dwsize + m*dsize + p;\n"; + + if (fPoolMode == MaxPool) { + out << SP << SP << SP << SP << SP << SP << SP << SP << "auto xval = tensor_" << fNX << "[index];\n"; + out << SP << SP << SP << SP << SP << SP << SP << SP << "if (xval > value) value = xval;\n"; + } + else if (fPoolMode == AveragePool) { + // compute sum of values + out << SP << SP << SP << SP << SP << SP << SP << SP << "value += tensor_" << fNX << "[index];\n"; + if (fAttrCountIncludePad == 0 && doPadding) + // compute number of elements used for the average + out << SP << SP << SP << SP << SP << SP << SP << SP << "nsum++;\n"; + } + out << SP << SP << SP << SP << SP << SP << "}\n"; + out << SP << SP << SP << SP << SP << "}\n"; + out << SP << SP << SP << SP << "}\n"; // end loop on region elements + if (fPoolMode == AveragePool) { + // compute average + out << SP << SP << SP << SP << "value /= float(nsum);\n"; + } - out << SP << SP << SP << SP << "tensor_" << fNY << "[outIndex++] = value;\n"; - out << SP << SP << SP << "}\n"; // end loop on j (columns of image) - out << SP << SP << "}\n"; // end loop on i (image rows) - out << SP << "}\n"; // end loop on c*b + out << SP << SP << SP << SP << "tensor_" << fNY << "[outIndex++] = value;\n"; + out << SP << SP << SP << SP << "}\n" ; // end loop on k (layers of image) + out << SP << SP << SP << "}\n"; // end loop on j (columns of image) + out << SP << SP << "}\n"; // end loop on i (image rows) + out << SP << "}\n"; // end loop on c*b + } // end scope - out << SP << "}\n"; + out << SP << "}\n"; + - return out.str(); } }; diff --git a/tmva/sofie/test/TestCustomModelsFromONNX.cxx b/tmva/sofie/test/TestCustomModelsFromONNX.cxx index 57da92f9d9ee7..6da224fc641e2 100644 --- a/tmva/sofie/test/TestCustomModelsFromONNX.cxx +++ b/tmva/sofie/test/TestCustomModelsFromONNX.cxx @@ -36,6 +36,18 @@ #include "ConvWithAsymmetricPadding_FromONNX.hxx" #include "input_models/references/ConvWithAsymmetricPadding.ref.hxx" +#include "MaxPool1d_FromONNX.hxx" +#include "input_models/references/MaxPool1d.ref.hxx" + +#include "MaxPool2d_FromONNX.hxx" +#include "input_models/references/MaxPool2d.ref.hxx" + +#include "MaxPool3d_FromONNX.hxx" +#include "input_models/references/MaxPool3d.ref.hxx" + +#include "AvgPool_FromONNX.hxx" +#include "input_models/references/AvgPool.ref.hxx" + #include "RNNBatchwise_FromONNX.hxx" #include "input_models/references/RNNBatchwise.ref.hxx" @@ -360,6 +372,131 @@ TEST(DISABLED_ONNX, ConvWithAsymmetricPadding) } } +TEST(ONNX, MaxPool1d){ + constexpr float TOLERANCE = DEFAULT_TOLERANCE; + + // Preparing the standard input + std::vector input({0.0907, 0.1029, 0.8143, 1.4497, -0.7785, 0.3825, -0.3764, + 1.5785, -0.0835, 0.1622, + 1.5867, 0.9823, -0.8821, 0.4439, -0.1378, -0.2273, -0.0198, + -2.0230, 0.0905, 0.6674, + -1.4290, -1.3100, -0.9439, -0.0833, -0.1919, 0.6886, 0.9389, + -1.2914, -1.3584, -2.0341, + -0.3269, 0.1704, 1.1776, 1.3972, -1.8874, -1.5334, 1.1541, + 0.3011, 0.6569, -2.3504, + 0.4033, 0.1142, 2.2846, -1.3948, -0.8573, 0.5756, -1.0864, + 0.2283, 0.8947, 1.7627, + -0.1657, 0.0649, -1.6066, 0.4162, -1.1525, -0.8184, 1.1324, + -1.1086, 0.1061, 1.0071}); + + TMVA_SOFIE_MaxPool1d::Session s("MaxPool1d_FromONNX.dat"); + std::vector output = s.infer(input.data()); + // Checking output size + EXPECT_EQ(output.size(), sizeof(MaxPool1d_ExpectedOutput::output) / sizeof(float)); + + float *correct = MaxPool1d_ExpectedOutput::output; + + // Checking every output value, one by one + for (size_t i = 0; i < output.size(); ++i) { + EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); + } + +} + +TEST(ONNX, MaxPool2d){ + constexpr float TOLERANCE = DEFAULT_TOLERANCE; + + // Preparing the standard input + std::vector input({ + 0.6266, 0.1656, 0.2753, -0.4558, -1.4592, 0.9285, -1.3410, + 1.3223, -0.5936, -1.3648, + -0.2989, 0.5901, -0.8845, -0.0433, 0.8314, -1.7159, -0.5765, + 0.8678, 1.0257, 0.7847, + -0.3421, -1.2364, -0.5805, 0.4421, 1.2184, 0.5043, 1.6823, + -1.0483, -2.2798, -1.8927, + 0.7716, 0.0405, 0.3121, -0.3011, -0.3266, -1.9660, 1.0837, + 0.2317, 0.9084, -0.3285, + -0.9398, -0.2065, -0.9499, -0.9739, -0.1288, -0.1375, -1.2612, + 0.8810, 0.8506, 0.4455 + }); + + TMVA_SOFIE_MaxPool2d::Session s("MaxPool2d_FromONNX.dat"); + std::vector output = s.infer(input.data()); + // Checking output size + EXPECT_EQ(output.size(), sizeof(MaxPool2d_ExpectedOutput::output) / sizeof(float)); + + float *correct = MaxPool2d_ExpectedOutput::output; + + // Checking every output value, one by one + for (size_t i = 0; i < output.size(); ++i) { + EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); + } + +} + +TEST(ONNX, MaxPool3d){ + constexpr float TOLERANCE = DEFAULT_TOLERANCE; + + // Preparing the standard input + std::vector input({ + -2.6496, 1.0476, -0.5153, + 0.3771, 0.4129, -0.3077, + -0.8717, -0.8040, -0.3525, + + -0.1765, -0.3364, 0.8737, + -0.2381, -0.8297, 0.4666, + 0.6984, -0.6760, 0.6298, + + 1.3833, 0.1101, 0.2039, + -0.5477, 0.2341, 0.9181, + 0.3842, 0.2428, 1.7924 + }); + + TMVA_SOFIE_MaxPool3d::Session s("MaxPool3d_FromONNX.dat"); + std::vector output = s.infer(input.data()); + // Checking output size + EXPECT_EQ(output.size(), sizeof(MaxPool3d_ExpectedOutput::output) / sizeof(float)); + + float *correct = MaxPool3d_ExpectedOutput::output; + + // Checking every output value, one by one + for (size_t i = 0; i < output.size(); ++i) { + EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); + } + +} + +TEST(ONNX, AvgPool){ + constexpr float TOLERANCE = DEFAULT_TOLERANCE; + + // Preparing the standard input + std::vector input({ + 0.4764, -0.1976, 1.6506, -0.2421, 0.6412, 1.9985, 0.3938, + 0.1347, 0.2204, -0.7503, + 0.2139, 0.7285, -0.0210, -0.4585, -1.5333, -0.4772, 0.5560, + 0.6323, -2.5372, 1.4906, + -1.1062, -0.9703, 0.2366, -0.9184, 0.3014, 0.7985, -0.6841, + -2.2854, -2.7728, -1.2806, + -1.0947, -0.5990, -0.3033, -1.9042, -0.5403, 0.2332, 0.9215, + -0.1549, 0.0557, -0.5567, + -1.4971, 0.5386, -0.2922, 0.4860, -0.3973, -0.4624, 0.4514, + 0.2385, 0.3783, -1.0500 + }); + + TMVA_SOFIE_AvgPool::Session s("AvgPool_FromONNX.dat"); + std::vector output = s.infer(input.data()); + // Checking output size + EXPECT_EQ(output.size(), sizeof(AvgPool_ExpectedOutput::output) / sizeof(float)); + + float *correct = AvgPool_ExpectedOutput::output; + + // Checking every output value, one by one + for (size_t i = 0; i < output.size(); ++i) { + EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); + } + +} + TEST(ONNX, RNNBatchwise) { constexpr float TOLERANCE = DEFAULT_TOLERANCE; diff --git a/tmva/sofie/test/input_models/AvgPool.onnx b/tmva/sofie/test/input_models/AvgPool.onnx new file mode 100644 index 0000000000000000000000000000000000000000..bb0c140ce21b546917afad7e0fe32509740cb57b GIT binary patch literal 220 zcmd;J5n?Z>EXglQ&X8g=)H5{HGq5_q$d$pxou8LiVPzGNm=bRw#AqbN>sXdrl$f3x zke{CuZ>YqL#MKhz;>k`e%1h0OFV09TNOfR#U|PV)t|iFDQjnNZ?7#qlARz%R_TrMF z%#_q(2POwbpoowF*lyjd%o5$yih}&2k|EXglQ&X8g=)H5{HGqBpg$Q8rIpP!dkVP)l;SP_t)pA&B&#AqnR3Fj%X zLz!B_Ts+ySMR}X51*s0q3mDn8c)3^#5>tvD7#tWtTs|)L;*z4wl+ literal 0 HcmV?d00001 diff --git a/tmva/sofie/test/input_models/MaxPool2d.onnx b/tmva/sofie/test/input_models/MaxPool2d.onnx new file mode 100644 index 0000000000000000000000000000000000000000..6427d59ce6e9d460a99ec9b4a93d1bc86727bc98 GIT binary patch literal 218 zcmd;J5n?Z>EXglQ&X8g=)H5{HGq5_q$d$sypP!dkVP)l;SP_t)pA&B&#AqnR3Fj%X zLz!BlTs+ySMR}X51*s0q4onLe*|h|@SPBwTiX9jr5F{kP#a>)el$nxR?7-;2 z2ow<#0NbmZm06;jT2YW+R1&3$X|EWU2nVB(02dPnBNVd&X|5z`E=EHkOi5;-B&QRT G04D%6a4+%z literal 0 HcmV?d00001 diff --git a/tmva/sofie/test/input_models/MaxPool3d.onnx b/tmva/sofie/test/input_models/MaxPool3d.onnx new file mode 100644 index 0000000000000000000000000000000000000000..e88616c9d94e99d0b49e8d1dc270b79424487ab9 GIT binary patch literal 234 zcmd;J5n?Z>EXglQ&X8g=)H5{HGqAeA$d$vzpP!dkVP)l;SP_t)pA&B&#AqnR3Fj%X zLz!CQTs+ySMR}X51*s0q4onVA3mDn8M7dZB5>tvD7!VL7EX2iLTvC*ol3MJ* z2!cQ{Apx-cx>=bex~UZf`9&pBx|sG$aY=A63W;zraWFzLGmr-3BzZ1ILm^BBAcagI J?8GF%2>>fnF;D;i literal 0 HcmV?d00001 diff --git a/tmva/sofie/test/input_models/references/AvgPool.ref.hxx b/tmva/sofie/test/input_models/references/AvgPool.ref.hxx new file mode 100644 index 0000000000000..6af63c85ddd2b --- /dev/null +++ b/tmva/sofie/test/input_models/references/AvgPool.ref.hxx @@ -0,0 +1,6 @@ +namespace AvgPool_ExpectedOutput { +float output[] = {-0.1425, 0.2378, 0.0412, -0.3683, 0.2882, 0.4309, -0.2088, + -1.1013, -0.9383, + -0.7881, -0.2316, -0.4493, -0.4955, -0.0111, 0.2097, -0.2522, + -0.7568, -0.8710}; +} // namespace AvgPool_ExpectedOutput \ No newline at end of file diff --git a/tmva/sofie/test/input_models/references/MaxPool1d.ref.hxx b/tmva/sofie/test/input_models/references/MaxPool1d.ref.hxx new file mode 100644 index 0000000000000..c1b15dccdcce2 --- /dev/null +++ b/tmva/sofie/test/input_models/references/MaxPool1d.ref.hxx @@ -0,0 +1,14 @@ +namespace MaxPool1d_ExpectedOutput { +float output[] = {0.8143, 1.4497, 1.4497, 1.4497, 0.3825, 1.5785, 1.5785, + 1.5785, + 1.5867, 0.9823, 0.4439, 0.4439, -0.0198, -0.0198, 0.0905, + 0.6674, + -0.9439, -0.0833, -0.0833, 0.6886, 0.9389, 0.9389, 0.9389, + -1.2914, + 1.1776, 1.3972, 1.3972, 1.3972, 1.1541, 1.1541, 1.1541, + 0.6569, + 2.2846, 2.2846, 2.2846, 0.5756, 0.5756, 0.5756, 0.8947, + 1.7627, + 0.0649, 0.4162, 0.4162, 0.4162, 1.1324, 1.1324, 1.1324, + 1.0071}; +} // namespace MaxPool1d_ExpectedOutput \ No newline at end of file diff --git a/tmva/sofie/test/input_models/references/MaxPool2d.ref.hxx b/tmva/sofie/test/input_models/references/MaxPool2d.ref.hxx new file mode 100644 index 0000000000000..fdcc0e55cc94a --- /dev/null +++ b/tmva/sofie/test/input_models/references/MaxPool2d.ref.hxx @@ -0,0 +1,8 @@ +namespace MaxPool2d_ExpectedOutput { +float output[] = {0.6266, 0.5901, 0.4421, 1.2184, 1.2184, 1.6823, 1.6823, 1.3223, + 1.0257, + 0.7716, 0.5901, 0.4421, 1.2184, 1.2184, 1.6823, 1.6823, 1.0257, + 1.0257, + 0.7716, 0.3121, 0.4421, 1.2184, 1.2184, 1.6823, 1.6823, 0.9084, + 0.9084}; +} // namespace MaxPool2d_ExpectedOutput \ No newline at end of file diff --git a/tmva/sofie/test/input_models/references/MaxPool3d.ref.hxx b/tmva/sofie/test/input_models/references/MaxPool3d.ref.hxx new file mode 100644 index 0000000000000..08263aa950d66 --- /dev/null +++ b/tmva/sofie/test/input_models/references/MaxPool3d.ref.hxx @@ -0,0 +1,6 @@ +namespace MaxPool3d_ExpectedOutput { +float output[] = { + 1.3833, 1.0476, + 0.6984, 1.7924 +}; +} // namespace MaxPool3d_ExpectedOutput \ No newline at end of file From 3645164fb81cf37c402f0a1a6a697c29dc19e120 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Wed, 29 Jun 2022 17:14:27 +0200 Subject: [PATCH 095/104] [RF] Fix dirty flag resetting when the normalization set is changed If the proxy normSet changed, we also have to set the value dirty flag of the proxy owner. Otherwise, value for the new normalization set might not get recomputed, which causes bugs! The issue can be reproduced with this small code snippet: ```C++ using namespace RooFit; RooRealVar x("x", "x", 0, -10, 10); RooGaussian gauss("gauss", "gauss", x, RooConst(0), RooConst(2)); RooAddition add("add", "add", {gauss}); std::cout << add.getVal() << std::endl; std::cout << add.getVal(x) << std::endl; ``` Without this commit, the value will be the same with and without normalization set, because changing only the normalization set didn't trigger a recomputation. This code snippet has also been implemented as a unit test now, where it is tested that the values are different. --- roofit/roofitcore/src/RooAbsArg.cxx | 4 ++++ roofit/roofitcore/test/testRooAbsPdf.cxx | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/roofit/roofitcore/src/RooAbsArg.cxx b/roofit/roofitcore/src/RooAbsArg.cxx index bc94e815afcc5..26d2ceda19558 100644 --- a/roofit/roofitcore/src/RooAbsArg.cxx +++ b/roofit/roofitcore/src/RooAbsArg.cxx @@ -1390,6 +1390,10 @@ void RooAbsArg::setProxyNormSet(const RooArgSet* nset) for ( auto& p : _proxyListCache.cache ) { p->changeNormSet(nset); } + + // If the proxy normSet changed, we also have to set our value dirty flag. + // Otherwise, value for the new normalization set might not get recomputed! + setValueDirty(); } diff --git a/roofit/roofitcore/test/testRooAbsPdf.cxx b/roofit/roofitcore/test/testRooAbsPdf.cxx index 2c6d3bc6076e8..cf98485ab86c9 100644 --- a/roofit/roofitcore/test/testRooAbsPdf.cxx +++ b/roofit/roofitcore/test/testRooAbsPdf.cxx @@ -2,6 +2,7 @@ // Authors: Stephan Hageboeck, CERN 04/2020 // Jonas Rembser, CERN 04/2021 +#include #include #include #include @@ -328,3 +329,21 @@ TEST(RooAbsPdf, ProblemsWith2DSimultaneousFit) simPdf.fitTo(data, PrintLevel(-1)); } + +// Verifies that a server pdf gets correctly reevaluated when the normalization +// set is changed. +TEST(RooAbsPdf, NormSetChange) +{ + using namespace RooFit; + + RooRealVar x("x", "x", 0, -10, 10); + RooGaussian gauss("gauss", "gauss", x, RooConst(0), RooConst(2)); + RooAddition add("add", "add", {gauss}); + + double v1 = add.getVal(); + double v2 = add.getVal(x); + + // The change of normalization set should trigger a recomputation of the + // value, so val2 should be different from val1. } + EXPECT_NE(v1, v2); +} From 1f0d5ada9623a4f212b58b794d6b235d0b8d8299 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Wed, 29 Jun 2022 01:14:27 +0200 Subject: [PATCH 096/104] [RF] Avoid duplication of RooRealSumPdf code in RooAddition Much of the functionality of RooAddition is implemented in exactly the same way as in RooRealSumPdf. Hence, to avoid code duplication, we can reuse the static functions in RooRealSumPdf that provide this implementation. --- roofit/roofitcore/inc/RooAddition.h | 6 +- roofit/roofitcore/inc/RooRealSumPdf.h | 2 + roofit/roofitcore/src/RooAddition.cxx | 173 +++----------------------- 3 files changed, 23 insertions(+), 158 deletions(-) diff --git a/roofit/roofitcore/inc/RooAddition.h b/roofit/roofitcore/inc/RooAddition.h index 0febdc81e852a..1b703b4411212 100644 --- a/roofit/roofitcore/inc/RooAddition.h +++ b/roofit/roofitcore/inc/RooAddition.h @@ -27,10 +27,9 @@ class RooArgList ; class RooAddition : public RooAbsReal { public: - RooAddition() ; + RooAddition() : _cacheMgr(this,10) {} RooAddition(const char *name, const char *title, const RooArgList& sumSet, bool takeOwnerShip=false) ; RooAddition(const char *name, const char *title, const RooArgList& sumSet1, const RooArgList& sumSet2, bool takeOwnerShip=false) ; - ~RooAddition() override ; RooAddition(const RooAddition& other, const char* name = 0); TObject* clone(const char* newname) const override { return new RooAddition(*this, newname); } @@ -66,10 +65,9 @@ class RooAddition : public RooAbsReal { class CacheElem : public RooAbsCacheElement { public: - ~CacheElem() override; // Payload RooArgList _I ; - RooArgList containedArgs(Action) override ; + RooArgList containedArgs(Action) override { return _I; } }; mutable RooObjCacheManager _cacheMgr ; /// #include -using namespace std; - ClassImp(RooAddition); -; - - -//////////////////////////////////////////////////////////////////////////////// -/// Empty constructor -RooAddition::RooAddition() : _cacheMgr(this,10) -{ -} - //////////////////////////////////////////////////////////////////////////////// @@ -70,7 +61,7 @@ RooAddition::RooAddition(const char* name, const char* title, const RooArgList& for (const auto comp : sumSet) { if (!dynamic_cast(comp)) { coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: component " << comp->GetName() - << " is not of type RooAbsReal" << endl ; + << " is not of type RooAbsReal" << std::endl; RooErrorHandler::softAbort() ; } _set.add(*comp) ; @@ -101,7 +92,7 @@ RooAddition::RooAddition(const char* name, const char* title, const RooArgList& , _cacheMgr(this,10) { if (sumSet1.getSize() != sumSet2.getSize()) { - coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: input lists should be of equal length" << endl ; + coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: input lists should be of equal length" << std::endl; RooErrorHandler::softAbort() ; } @@ -111,13 +102,13 @@ RooAddition::RooAddition(const char* name, const char* title, const RooArgList& if (!dynamic_cast(comp1)) { coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: component " << comp1->GetName() - << " in first list is not of type RooAbsReal" << endl ; + << " in first list is not of type RooAbsReal" << std::endl; RooErrorHandler::softAbort() ; } if (!dynamic_cast(comp2)) { coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: component " << comp2->GetName() - << " in first list is not of type RooAbsReal" << endl ; + << " in first list is not of type RooAbsReal" << std::endl; RooErrorHandler::softAbort() ; } // TODO: add flag to RooProduct c'tor to make it assume ownership... @@ -150,14 +141,6 @@ RooAddition::RooAddition(const RooAddition& other, const char* name) // Member _ownedList is intentionally not copy-constructed -- ownership is not transferred } - -//////////////////////////////////////////////////////////////////////////////// - -RooAddition::~RooAddition() -{ // Destructor - -} - //////////////////////////////////////////////////////////////////////////////// /// Calculate and return current value of self @@ -166,15 +149,10 @@ double RooAddition::evaluate() const double sum(0); const RooArgSet* nset = _set.nset() ; -// cout << "RooAddition::eval sum = " ; - - for (const auto arg : _set) { - const auto comp = static_cast(arg); + for (auto* comp : static_range_cast(_set)) { const double tmp = comp->getVal(nset); -// cout << tmp << " " ; sum += tmp ; } -// cout << " = " << sum << endl ; return sum ; } @@ -211,7 +189,7 @@ double RooAddition::defaultErrorLevel() const RooAbsReal* nllArg(0) ; RooAbsReal* chi2Arg(0) ; - RooArgSet* comps = getComponents() ; + std::unique_ptr comps{getComponents()}; for(RooAbsArg * arg : *comps) { if (dynamic_cast(arg) || dynamic_cast(arg)) { nllArg = (RooAbsReal*)arg ; @@ -220,22 +198,21 @@ double RooAddition::defaultErrorLevel() const chi2Arg = (RooAbsReal*)arg ; } } - delete comps ; if (nllArg && !chi2Arg) { coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName() - << ") Summation contains a RooNLLVar, using its error level" << endl ; + << ") Summation contains a RooNLLVar, using its error level" << std::endl; return nllArg->defaultErrorLevel() ; } else if (chi2Arg && !nllArg) { coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName() - << ") Summation contains a RooChi2Var, using its error level" << endl ; + << ") Summation contains a RooChi2Var, using its error level" << std::endl; return chi2Arg->defaultErrorLevel() ; } else if (!nllArg && !chi2Arg) { coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName() << ") WARNING: " - << "Summation contains neither RooNLLVar nor RooChi2Var server, using default level of 1.0" << endl ; + << "Summation contains neither RooNLLVar nor RooChi2Var server, using default level of 1.0" << std::endl; } else { coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName() << ") WARNING: " - << "Summation contains BOTH RooNLLVar and RooChi2Var server, using default level of 1.0" << endl ; + << "Summation contains BOTH RooNLLVar and RooChi2Var server, using default level of 1.0" << std::endl; } return 1.0 ; @@ -267,18 +244,11 @@ bool RooAddition::setData(RooAbsData& data, bool cloneData) //////////////////////////////////////////////////////////////////////////////// -void RooAddition::printMetaArgs(ostream& os) const +void RooAddition::printMetaArgs(std::ostream& os) const { - bool first(true) ; - for (const auto arg : _set) { - if (!first) { - os << " + " ; - } else { - first = false ; - } - os << arg->GetName() ; - } - os << " " ; + // We can use the implementation of RooRealSumPdf with an empy coefficient list. + static const RooArgList coefs{}; + RooRealSumPdf::printMetaArgs(_set, coefs, os); } //////////////////////////////////////////////////////////////////////////////// @@ -335,128 +305,23 @@ double RooAddition::analyticalIntegral(Int_t code, const char* rangeName) const } - //////////////////////////////////////////////////////////////////////////////// std::list* RooAddition::binBoundaries(RooAbsRealLValue& obs, double xlo, double xhi) const { - std::list* sumBinB = 0 ; - bool needClean(false) ; - - // Loop over components pdf - for(auto * func : static_range_cast(_set)) { - - std::list* funcBinB = func->binBoundaries(obs,xlo,xhi) ; - - // Process hint - if (funcBinB) { - if (!sumBinB) { - // If this is the first hint, then just save it - sumBinB = funcBinB ; - } else { - - std::list* newSumBinB = new std::list(sumBinB->size()+funcBinB->size()) ; - - // Merge hints into temporary array - merge(funcBinB->begin(),funcBinB->end(),sumBinB->begin(),sumBinB->end(),newSumBinB->begin()) ; - - // Copy merged array without duplicates to new sumBinBArrau - delete sumBinB ; - delete funcBinB ; - sumBinB = newSumBinB ; - needClean = true ; - } - } - } - - // Remove consecutive duplicates - if (needClean) { - std::list::iterator new_end = unique(sumBinB->begin(),sumBinB->end()) ; - sumBinB->erase(new_end,sumBinB->end()) ; - } - - return sumBinB ; + return RooRealSumPdf::binBoundaries(_set, obs, xlo, xhi); } -//_____________________________________________________________________________B bool RooAddition::isBinnedDistribution(const RooArgSet& obs) const { - // If all components that depend on obs are binned that so is the product - - RooFIter iter = _set.fwdIterator() ; - RooAbsReal* func ; - while((func=(RooAbsReal*)iter.next())) { - if (func->dependsOn(obs) && !func->isBinnedDistribution(obs)) { - return false ; - } - } - - return true ; + return RooRealSumPdf::isBinnedDistribution(_set, obs); } - - //////////////////////////////////////////////////////////////////////////////// std::list* RooAddition::plotSamplingHint(RooAbsRealLValue& obs, double xlo, double xhi) const { - std::list* sumHint = 0 ; - bool needClean(false) ; - - RooFIter iter = _set.fwdIterator() ; - RooAbsReal* func ; - // Loop over components pdf - while((func=(RooAbsReal*)iter.next())) { - - std::list* funcHint = func->plotSamplingHint(obs,xlo,xhi) ; - - // Process hint - if (funcHint) { - if (!sumHint) { - - // If this is the first hint, then just save it - sumHint = funcHint ; - - } else { - - std::list* newSumHint = new std::list(sumHint->size()+funcHint->size()) ; - - // Merge hints into temporary array - merge(funcHint->begin(),funcHint->end(),sumHint->begin(),sumHint->end(),newSumHint->begin()) ; - - // Copy merged array without duplicates to new sumHintArrau - delete sumHint ; - sumHint = newSumHint ; - needClean = true ; - } - } - } - - // Remove consecutive duplicates - if (needClean) { - std::list::iterator new_end = unique(sumHint->begin(),sumHint->end()) ; - sumHint->erase(new_end,sumHint->end()) ; - } - - return sumHint ; -} - - - -//////////////////////////////////////////////////////////////////////////////// -/// Return list of all RooAbsArgs in cache element - -RooArgList RooAddition::CacheElem::containedArgs(Action) -{ - RooArgList ret(_I) ; - return ret ; + return RooRealSumPdf::plotSamplingHint(_set, obs, xlo, xhi); } - -RooAddition::CacheElem::~CacheElem() -{ - // Destructor -} - - From 6fa5c443bce19355f1125152c08c18277493657e Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Wed, 29 Jun 2022 01:15:12 +0200 Subject: [PATCH 097/104] [RF] Avoid duplication of RooRealSumPdf code in RooAddPdf Much of the functionality of RooAddPdf is implemented in exactly the same way as in RooRealSumPdf. Hence, to avoid code duplication, we can reuse the static functions in RooRealSumPdf that provide this implementation. --- roofit/roofitcore/src/RooAddPdf.cxx | 141 ++---------------------- roofit/roofitcore/src/RooRealSumPdf.cxx | 7 +- 2 files changed, 11 insertions(+), 137 deletions(-) diff --git a/roofit/roofitcore/src/RooAddPdf.cxx b/roofit/roofitcore/src/RooAddPdf.cxx index 8518d0f10143b..0edb292fcdda4 100644 --- a/roofit/roofitcore/src/RooAddPdf.cxx +++ b/roofit/roofitcore/src/RooAddPdf.cxx @@ -74,6 +74,7 @@ An (enforced) condition for this assumption is that each \f$ \mathrm{PDF}_i \f$ #include "RooRealVar.h" #include "RooRealConstant.h" #include "RooRealIntegral.h" +#include "RooRealSumPdf.h" #include "RooRecursiveFraction.h" #include @@ -823,21 +824,7 @@ void RooAddPdf::resetErrorCounters(Int_t resetValue) bool RooAddPdf::checkObservables(const RooArgSet* nset) const { - bool ret(false) ; - - // There may be fewer coefficients than PDFs. - std::size_t end = std::min(_pdfList.size(), _coefList.size()); - for (std::size_t i = 0; i < end; ++i) { - auto pdf = static_cast(_pdfList.at(i)); - auto coef = static_cast(_coefList.at(i)); - if (pdf->observableOverlaps(nset,*coef)) { - coutE(InputArguments) << "RooAddPdf::checkObservables(" << GetName() << "): ERROR: coefficient " << coef->GetName() - << " and PDF " << pdf->GetName() << " have one or more dependents in common" << endl ; - ret = true ; - } - } - - return ret ; + return RooRealSumPdf::checkObservables(*this, nset, _pdfList, _coefList); } @@ -1079,41 +1066,7 @@ RooArgList RooAddPdf::CacheElem::containedArgs(Action) std::list* RooAddPdf::plotSamplingHint(RooAbsRealLValue& obs, double xlo, double xhi) const { - std::unique_ptr> sumHint = nullptr ; - bool needClean = false; - - // Loop over components pdf - for (const auto arg : _pdfList) { - auto pdf = static_cast(arg); - - std::unique_ptr> pdfHint{pdf->plotSamplingHint(obs,xlo,xhi)} ; - - // Process hint - if (pdfHint) { - if (!sumHint) { - - // If this is the first hint, then just save it - sumHint = std::move(pdfHint) ; - - } else { - - auto newSumHint = std::make_unique>(sumHint->size()+pdfHint->size()); - - // Merge hints into temporary array - merge(pdfHint->begin(),pdfHint->end(),sumHint->begin(),sumHint->end(),newSumHint->begin()) ; - - // Copy merged array without duplicates to new sumHintArrau - sumHint = std::move(newSumHint) ; - needClean = true ; - - } - } - } - if (needClean) { - sumHint->erase(std::unique(sumHint->begin(),sumHint->end()), sumHint->end()) ; - } - - return sumHint.release() ; + return RooRealSumPdf::plotSamplingHint(_pdfList, obs, xlo, xhi); } @@ -1122,41 +1075,7 @@ std::list* RooAddPdf::plotSamplingHint(RooAbsRealLValue& obs, double xlo std::list* RooAddPdf::binBoundaries(RooAbsRealLValue& obs, double xlo, double xhi) const { - std::unique_ptr> sumBinB = nullptr ; - bool needClean = false; - - // Loop over components pdf - for (auto arg : _pdfList) { - auto pdf = static_cast(arg); - std::unique_ptr> pdfBinB{pdf->binBoundaries(obs,xlo,xhi)}; - - // Process hint - if (pdfBinB) { - if (!sumBinB) { - - // If this is the first hint, then just save it - sumBinB = std::move(pdfBinB) ; - - } else { - - auto newSumBinB = std::make_unique>(sumBinB->size()+pdfBinB->size()) ; - - // Merge hints into temporary array - merge(pdfBinB->begin(),pdfBinB->end(),sumBinB->begin(),sumBinB->end(),newSumBinB->begin()) ; - - // Copy merged array without duplicates to new sumBinBArrau - sumBinB = std::move(newSumBinB) ; - needClean = true ; - } - } - } - - // Remove consecutive duplicates - if (needClean) { - sumBinB->erase(std::unique(sumBinB->begin(),sumBinB->end()), sumBinB->end()) ; - } - - return sumBinB.release() ; + return RooRealSumPdf::binBoundaries(_pdfList, obs, xlo, xhi); } @@ -1164,14 +1083,7 @@ std::list* RooAddPdf::binBoundaries(RooAbsRealLValue& obs, double xlo, d /// If all components that depend on obs are binned, so is their sum. bool RooAddPdf::isBinnedDistribution(const RooArgSet& obs) const { - for (const auto arg : _pdfList) { - auto pdf = static_cast(arg); - if (pdf->dependsOn(obs) && !pdf->isBinnedDistribution(obs)) { - return false ; - } - } - - return true ; + return RooRealSumPdf::isBinnedDistribution(_pdfList, obs); } @@ -1180,14 +1092,7 @@ bool RooAddPdf::isBinnedDistribution(const RooArgSet& obs) const void RooAddPdf::setCacheAndTrackHints(RooArgSet& trackNodes) { - RooFIter aiter = pdfList().fwdIterator() ; - RooAbsArg* aarg ; - while ((aarg=aiter.next())) { - if (aarg->canNodeBeCached()==Always) { - trackNodes.add(*aarg) ; - //cout << "tracking node RooAddPdf component " << aarg->ClassName() << "::" << aarg->GetName() << endl ; - } - } + RooRealSumPdf::setCacheAndTrackHints(_pdfList, trackNodes); } @@ -1196,37 +1101,7 @@ void RooAddPdf::setCacheAndTrackHints(RooArgSet& trackNodes) /// Customized printing of arguments of a RooAddPdf to more intuitively reflect the contents of the /// product operator construction -void RooAddPdf::printMetaArgs(ostream& os) const +void RooAddPdf::printMetaArgs(std::ostream& os) const { - bool first(true) ; - - if (!_coefList.empty()) { - for (std::size_t i = 0; i < _pdfList.size(); ++i ) { - const RooAbsArg * coef = _coefList.at(i); - const RooAbsArg * pdf = _pdfList.at(i); - if (!first) { - os << " + " ; - } else { - first = false ; - } - - if (i < _coefList.size()) { - os << coef->GetName() << " * " << pdf->GetName(); - } else { - os << "[%] * " << pdf->GetName(); - } - } - } else { - - for (const auto pdf : _pdfList) { - if (!first) { - os << " + " ; - } else { - first = false ; - } - os << pdf->GetName() ; - } - } - - os << " " ; + RooRealSumPdf::printMetaArgs(_pdfList, _coefList, os); } diff --git a/roofit/roofitcore/src/RooRealSumPdf.cxx b/roofit/roofitcore/src/RooRealSumPdf.cxx index ae7ce6d91c6a7..e766b33beecd7 100644 --- a/roofit/roofitcore/src/RooRealSumPdf.cxx +++ b/roofit/roofitcore/src/RooRealSumPdf.cxx @@ -602,8 +602,7 @@ bool RooRealSumPdf::isBinnedDistribution(const RooArgSet& obs) const bool RooRealSumPdf::isBinnedDistribution(RooArgList const& funcList, const RooArgSet& obs) { - for (const auto elm : funcList) { - auto func = static_cast(elm); + for (auto* func : static_range_cast(funcList)) { if (func->dependsOn(obs) && !func->isBinnedDistribution(obs)) { return false ; @@ -624,7 +623,7 @@ std::list* RooRealSumPdf::plotSamplingHint(RooAbsRealLValue& obs, double std::list* RooRealSumPdf::plotSamplingHint(RooArgList const& funcList, RooAbsRealLValue& obs, double xlo, double xhi) { - std::list* sumHint = 0 ; + std::list* sumHint = nullptr; bool needClean(false) ; // Loop over components pdf @@ -642,7 +641,7 @@ std::list* RooRealSumPdf::plotSamplingHint(RooArgList const& funcList, R } else { - list* newSumHint = new list(sumHint->size()+funcHint->size()) ; + auto* newSumHint = new std::list(sumHint->size()+funcHint->size()) ; // Merge hints into temporary array merge(funcHint->begin(),funcHint->end(),sumHint->begin(),sumHint->end(),newSumHint->begin()) ; From 61a102d3cecd23bb03f0bbc3ec1dcb896c5566cf Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 16:04:23 +0200 Subject: [PATCH 098/104] Protect TF1 constructor against nullptr as formula parameter Use more clear std::make_unique calls --- hist/hist/src/TF1.cxx | 44 ++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/hist/hist/src/TF1.cxx b/hist/hist/src/TF1.cxx index 55871e3610905..190e1c2576220 100644 --- a/hist/hist/src/TF1.cxx +++ b/hist/hist/src/TF1.cxx @@ -523,16 +523,16 @@ TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, EA TNamed(name, formula), TAttLine(), TAttFill(), TAttMarker(), fType(EFType::kFormula) { if (xmin < xmax) { - fXmin = xmin; - fXmax = xmax; + fXmin = xmin; + fXmax = xmax; } else { - fXmin = xmax; //when called from TF2,TF3 + fXmin = xmax; // when called from TF2,TF3 fXmax = xmin; } // Create rep formula (no need to add to gROOT list since we will add the TF1 object) - const auto formulaLength = strlen(formula); + const auto formulaLength = formula ? strlen(formula) : 0; // First check if we are making a convolution - if (strncmp(formula, "CONV(", 5) == 0 && formula[formulaLength - 1] == ')') { + if (formulaLength > 5 && strncmp(formula, "CONV(", 5) == 0 && formula[formulaLength - 1] == ')') { // Look for single ',' delimiter int delimPosition = -1; int parenCount = 0; @@ -559,15 +559,15 @@ TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, EA formula2.ReplaceAll(' ', ""); TF1 *function1 = (TF1 *)(gROOT->GetListOfFunctions()->FindObject(formula1)); - if (function1 == nullptr) - function1 = new TF1((const char *)formula1, (const char *)formula1, xmin, xmax); + if (!function1) + function1 = new TF1(formula1.Data(), formula1.Data(), xmin, xmax); TF1 *function2 = (TF1 *)(gROOT->GetListOfFunctions()->FindObject(formula2)); - if (function2 == nullptr) - function2 = new TF1((const char *)formula2, (const char *)formula2, xmin, xmax); + if (!function2) + function2 = new TF1(formula2.Data(), formula2.Data(), xmin, xmax); // std::cout << "functions have been defined" << std::endl; - TF1Convolution *conv = new TF1Convolution(function1, function2,xmin,xmax); + TF1Convolution *conv = new TF1Convolution(function1, function2, xmin, xmax); // (note: currently ignoring `useFFT` option) fNpar = conv->GetNpar(); @@ -576,7 +576,7 @@ TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, EA fType = EFType::kCompositionFcn; fComposition = std::unique_ptr(conv); - fParams = std::unique_ptr(new TF1Parameters(fNpar)); // default to zeros (TF1Convolution has no GetParameters()) + fParams = std::make_unique(fNpar); // default to zeros (TF1Convolution has no GetParameters()) // set parameter names for (int i = 0; i < fNpar; i++) this->SetParName(i, conv->GetParName(i)); @@ -605,7 +605,7 @@ TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, EA } // Then check if we need NSUM syntax: - } else if (strncmp(formula, "NSUM(", 5) == 0 && formula[formulaLength - 1] == ')') { + } else if (formulaLength > 5 && strncmp(formula, "NSUM(", 5) == 0 && formula[formulaLength - 1] == ')') { // using comma as delimiter char delimiter = ','; // first, remove "NSUM(" and ")" and spaces @@ -646,21 +646,21 @@ TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, EA fType = EFType::kCompositionFcn; fComposition = std::unique_ptr(normSum); - fParams = std::unique_ptr(new TF1Parameters(fNpar)); + fParams = std::make_unique(fNpar); fParams->SetParameters(&(normSum->GetParameters())[0]); // inherit default parameters from normSum // Parameter names for (int i = 0; i < fNpar; i++) { - if (coeffNames->At(i) != nullptr) { + if (coeffNames->At(i)) { TString coeffName = ((TObjString *)coeffNames->At(i))->GetString(); - this->SetParName(i, (const char *)coeffName); + this->SetParName(i, coeffName.Data()); } else { this->SetParName(i, normSum->GetParName(i)); } } } else { // regular TFormula - fFormula = std::unique_ptr(new TFormula(name, formula, false, vectorize)); + fFormula = std::make_unique(name, formula, false, vectorize); fNpar = fFormula->GetNpar(); // TFormula can have dimension zero, but since this is a TF1 minimal dim is 1 fNdim = fFormula->GetNdim() == 0 ? 1 : fFormula->GetNdim(); @@ -679,7 +679,9 @@ TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, EA DoInitialize(addToGlobList); } -TF1::EAddToList GetGlobalListOption(Option_t * opt) { + +TF1::EAddToList GetGlobalListOption(Option_t * opt) +{ if (opt == nullptr) return TF1::EAddToList::kDefault; TString option(opt); option.ToUpper(); @@ -687,13 +689,16 @@ TF1::EAddToList GetGlobalListOption(Option_t * opt) { if (option.Contains("GL")) return TF1::EAddToList::kAdd; return TF1::EAddToList::kDefault; } -bool GetVectorizedOption(Option_t * opt) { - if (opt == nullptr) return false; + +bool GetVectorizedOption(Option_t * opt) +{ + if (!opt) return false; TString option(opt); option.ToUpper(); if (option.Contains("VEC")) return true; return false; } + TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, Option_t * opt) : //////////////////////////////////////////////////////////////////////////////// /// Same constructor as above (for TFormula based function) but passing an option strings @@ -705,6 +710,7 @@ TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, Op /////////////////////////////////////////////////////////////////////////////////// TF1(name, formula, xmin, xmax, GetGlobalListOption(opt), GetVectorizedOption(opt) ) {} + //////////////////////////////////////////////////////////////////////////////// /// F1 constructor using name of an interpreted function. /// From 1d206215484a4209ba8d8a62403032bc843bd215 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 16:19:22 +0200 Subject: [PATCH 099/104] Fix memory leak in TF1 constructor NSUM(...) parsing Created list of functions and list of parameters names was not deleted properly. --- hist/hist/src/TF1.cxx | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/hist/hist/src/TF1.cxx b/hist/hist/src/TF1.cxx index 190e1c2576220..54de71a8fe125 100644 --- a/hist/hist/src/TF1.cxx +++ b/hist/hist/src/TF1.cxx @@ -618,11 +618,11 @@ TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, EA // Go char-by-char to split terms and define the relevant functions int parenCount = 0; int termStart = 0; - TObjArray *newFuncs = new TObjArray(); - newFuncs->SetOwner(kTRUE); - TObjArray *coeffNames = new TObjArray(); - coeffNames->SetOwner(kTRUE); - TString fullFormula(""); + TObjArray newFuncs; + newFuncs.SetOwner(kTRUE); + TObjArray coeffNames; + coeffNames.SetOwner(kTRUE); + TString fullFormula; for (int i = 0; i < formDense.Length(); ++i) { if (formDense[i] == '(') parenCount++; @@ -630,11 +630,11 @@ TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, EA parenCount--; else if (formDense[i] == delimiter && parenCount == 0) { // term goes from termStart to i - DefineNSUMTerm(newFuncs, coeffNames, fullFormula, formDense, termStart, i, xmin, xmax); + DefineNSUMTerm(&newFuncs, &coeffNames, fullFormula, formDense, termStart, i, xmin, xmax); termStart = i + 1; } } - DefineNSUMTerm(newFuncs, coeffNames, fullFormula, formDense, termStart, formDense.Length(), xmin, xmax); + DefineNSUMTerm(&newFuncs, &coeffNames, fullFormula, formDense, termStart, formDense.Length(), xmin, xmax); TF1NormSum *normSum = new TF1NormSum(fullFormula, xmin, xmax); @@ -651,9 +651,8 @@ TF1::TF1(const char *name, const char *formula, Double_t xmin, Double_t xmax, EA // Parameter names for (int i = 0; i < fNpar; i++) { - if (coeffNames->At(i)) { - TString coeffName = ((TObjString *)coeffNames->At(i))->GetString(); - this->SetParName(i, coeffName.Data()); + if (coeffNames.At(i)) { + this->SetParName(i, coeffNames.At(i)->GetName()); } else { this->SetParName(i, normSum->GetParName(i)); } From 8baea4ce9a22f1f88e723e03d610d5a49287978e Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Wed, 29 Jun 2022 16:20:20 +0200 Subject: [PATCH 100/104] Protect hist classes against calling strlen with nullptr argument --- hist/hist/src/TFormula.cxx | 3 ++- hist/hist/src/TFormula_v5.cxx | 2 +- hist/hist/src/TGraph.cxx | 2 +- hist/hist/src/TGraphTime.cxx | 11 +++++++---- hist/hist/src/TH1.cxx | 6 ++++-- hist/hist/src/TMultiGraph.cxx | 2 +- hist/hist/src/TPrincipal.cxx | 6 +++--- hist/hist/src/TProfile2D.cxx | 2 +- 8 files changed, 20 insertions(+), 14 deletions(-) diff --git a/hist/hist/src/TFormula.cxx b/hist/hist/src/TFormula.cxx index 0b0a55b57c97d..2ef4bf5419464 100644 --- a/hist/hist/src/TFormula.cxx +++ b/hist/hist/src/TFormula.cxx @@ -453,7 +453,8 @@ TFormula::TFormula() } //////////////////////////////////////////////////////////////////////////////// -static bool IsReservedName(const char* name){ +static bool IsReservedName(const char* name) +{ if (strlen(name)!=1) return false; for (auto const & specialName : {"x","y","z","t"}){ if (strcmp(name,specialName)==0) return true; diff --git a/hist/hist/src/TFormula_v5.cxx b/hist/hist/src/TFormula_v5.cxx index dd30c471418ca..0045cb9bf3281 100644 --- a/hist/hist/src/TFormula_v5.cxx +++ b/hist/hist/src/TFormula_v5.cxx @@ -191,7 +191,7 @@ TFormula::TFormula(const char *name,const char *expression) : //eliminate blanks in expression Int_t i,j,nch; - nch = strlen(expression); + nch = expression ? strlen(expression) : 0; char *expr = new char[nch+1]; j = 0; for (i=0;iGetListOfPrimitives()->FindObject("TFrame")) opt = "alp"; } else { diff --git a/hist/hist/src/TGraphTime.cxx b/hist/hist/src/TGraphTime.cxx index 552cedc4ef57c..e7f00b662573c 100644 --- a/hist/hist/src/TGraphTime.cxx +++ b/hist/hist/src/TGraphTime.cxx @@ -174,7 +174,7 @@ void TGraphTime::Paint(Option_t *option) void TGraphTime::SaveAnimatedGif(const char *filename) const { TObject *frame = gPad->GetPrimitive("frame"); - TList *list = 0; + TList *list = nullptr; TObjLink *lnk; for (Int_t s=0;sNext(); } gPad->Update(); - if (strlen(filename) > 0) gPad->Print(Form("%s+",filename)); - else gPad->Print(Form("%s+",GetName())); - if (fSleepTime > 0) gSystem->Sleep(fSleepTime); + if (filename && strlen(filename) > 0) + gPad->Print(Form("%s+", filename)); + else + gPad->Print(Form("%s+", GetName())); + if (fSleepTime > 0) + gSystem->Sleep(fSleepTime); } } } diff --git a/hist/hist/src/TH1.cxx b/hist/hist/src/TH1.cxx index e7c7253d5a909..7a149b88431ce 100644 --- a/hist/hist/src/TH1.cxx +++ b/hist/hist/src/TH1.cxx @@ -6202,8 +6202,10 @@ void TH1::Paint(Option_t *option) GetPainter(option); if (fPainter) { - if (strlen(option) > 0) fPainter->Paint(option); - else fPainter->Paint(fOption.Data()); + if (option && strlen(option) > 0) + fPainter->Paint(option); + else + fPainter->Paint(fOption.Data()); } } diff --git a/hist/hist/src/TMultiGraph.cxx b/hist/hist/src/TMultiGraph.cxx index 1ecf832b2ddd7..2324810c6e2db 100644 --- a/hist/hist/src/TMultiGraph.cxx +++ b/hist/hist/src/TMultiGraph.cxx @@ -1132,7 +1132,7 @@ void TMultiGraph::Paint(Option_t *choptin) char option[128]; strlcpy(option,choptin,128); - Int_t nch = strlen(choptin); + Int_t nch = choptin ? strlen(choptin) : 0; for (Int_t i=0;i 0) { + while (opt && strlen(opt) > 0) { switch(*opt++) { case 'N': case 'n': @@ -580,7 +580,7 @@ void TPrincipal::MakeHistograms(const char *name, Option_t *opt) Bool_t makeE = kFALSE; Bool_t makeS = kFALSE; - Int_t len = strlen(opt); + Int_t len = opt ? strlen(opt) : 0; Int_t i,j,k; for (i = 0; i < len; i++) { switch (opt[i]) { @@ -1090,7 +1090,7 @@ void TPrincipal::Print(Option_t *opt) const Bool_t printS = kFALSE; Bool_t printE = kFALSE; - Int_t len = strlen(opt); + Int_t len = opt ? strlen(opt) : 0; for (Int_t i = 0; i < len; i++) { switch (opt[i]) { case 'V': diff --git a/hist/hist/src/TProfile2D.cxx b/hist/hist/src/TProfile2D.cxx index b7d22ddcb32f6..d9892582f0d60 100644 --- a/hist/hist/src/TProfile2D.cxx +++ b/hist/hist/src/TProfile2D.cxx @@ -1820,7 +1820,7 @@ TProfile2D * TProfile2D::Rebin2D(Int_t nxgroup ,Int_t nygroup,const char * newna } //nxgroup == nygroup == 1 else{ - if((newname) && (strlen(newname) > 0)) + if(newname && (strlen(newname) > 0)) return (TProfile2D*)Clone(newname); else return this; From 4e0ef333eac4b3e0fcccc13f60d6a5882558383b Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Thu, 30 Jun 2022 13:04:15 +0530 Subject: [PATCH 101/104] Some error messages and spelling mistakes fixed related to operators (#10435) * Some error messages and spelling mistakes fixed related to operaters * Update the indentation of BatchNormalization.hxx Co-authored-by: Neel Shah --- tmva/sofie/inc/TMVA/ROperator_Add.hxx | 4 +- .../inc/TMVA/ROperator_BatchNormalization.hxx | 334 +++++++++--------- tmva/sofie/inc/TMVA/ROperator_Conv.hxx | 20 +- tmva/sofie/inc/TMVA/ROperator_Gemm.hxx | 2 +- tmva/sofie/inc/TMVA/ROperator_Reshape.hxx | 4 +- tmva/sofie/inc/TMVA/ROperator_Slice.hxx | 2 +- 6 files changed, 183 insertions(+), 183 deletions(-) diff --git a/tmva/sofie/inc/TMVA/ROperator_Add.hxx b/tmva/sofie/inc/TMVA/ROperator_Add.hxx index c3d06222ba6b2..adaed3ea68ef4 100644 --- a/tmva/sofie/inc/TMVA/ROperator_Add.hxx +++ b/tmva/sofie/inc/TMVA/ROperator_Add.hxx @@ -45,14 +45,14 @@ public: throw std::runtime_error(std::string("TMVA SOFIE Add Op Input Tensor ") + fNX1 + "is not found in model"); } if (model.CheckIfTensorAlreadyExist(fNX2) == false) { - throw std::runtime_error(std::string("TMVA SOFIE Add Op Input Tensor ") + fNX1 + "is not found in model"); + throw std::runtime_error(std::string("TMVA SOFIE Add Op Input Tensor ") + fNX2 + "is not found in model"); } auto shapeX1 = model.GetTensorShape(fNX1); auto shapeX2 = model.GetTensorShape(fNX2); // assume same shape X1 and X2 if (shapeX1 != shapeX2) { std::string msg = "TMVA SOFIE Add Op: Support only inputs with same shape, shape 1 is " + - ConvertShapeToString(shapeX1) + "shape 2 is " + ConvertShapeToString(shapeX2); + ConvertShapeToString(shapeX1) + "and shape 2 is " + ConvertShapeToString(shapeX2); throw std::runtime_error(msg); } fShape = shapeX1; diff --git a/tmva/sofie/inc/TMVA/ROperator_BatchNormalization.hxx b/tmva/sofie/inc/TMVA/ROperator_BatchNormalization.hxx index 08e37389568f4..73d362e15361c 100644 --- a/tmva/sofie/inc/TMVA/ROperator_BatchNormalization.hxx +++ b/tmva/sofie/inc/TMVA/ROperator_BatchNormalization.hxx @@ -19,203 +19,203 @@ class ROperator_BatchNormalization final : public ROperator private: - /* Attributes */ - float fepsilon = 1e-05; - float fmomentum = 0.9; - std::size_t ftraining_mode = 0; - - std::string fNX; - std::string fNScale; - std::string fNB; - std::string fNMean; - std::string fNVar; - std::string fNY; - - std::vector fShapeX; - std::vector fShapeScale; - std::vector fShapeB; - std::vector fShapeMean; - std::vector fShapeVar; - std::vector fShapeY; - - std::string fType; + /* Attributes */ + float fepsilon = 1e-05; + float fmomentum = 0.9; + std::size_t ftraining_mode = 0; + + std::string fNX; + std::string fNScale; + std::string fNB; + std::string fNMean; + std::string fNVar; + std::string fNY; + + std::vector fShapeX; + std::vector fShapeScale; + std::vector fShapeB; + std::vector fShapeMean; + std::vector fShapeVar; + std::vector fShapeY; + + std::string fType; public: - ROperator_BatchNormalization() = delete; - - /* Constructor */ - ROperator_BatchNormalization( float epsilon, float momentum, std::size_t training_mode, - std::string nameX, std::string nameScale, std::string nameB, - std::string nameMean, std::string nameVar, std::string nameY): - fepsilon(epsilon), fmomentum(momentum), ftraining_mode(training_mode), - fNX(UTILITY::Clean_name(nameX)), fNScale(UTILITY::Clean_name(nameScale)), - fNB(UTILITY::Clean_name(nameB)), fNMean(UTILITY::Clean_name(nameMean)), - fNVar(UTILITY::Clean_name(nameVar)), fNY(UTILITY::Clean_name(nameY)) - { - if(std::is_same::value){ - fType = "float"; - } - else{ - throw - std::runtime_error("TMVA SOFIE Encountered unsupported type parsing a BatchNormalization operator"); - } - } + ROperator_BatchNormalization() = delete; + + /* Constructor */ + ROperator_BatchNormalization( float epsilon, float momentum, std::size_t training_mode, + std::string nameX, std::string nameScale, std::string nameB, + std::string nameMean, std::string nameVar, std::string nameY): + fepsilon(epsilon), fmomentum(momentum), ftraining_mode(training_mode), + fNX(UTILITY::Clean_name(nameX)), fNScale(UTILITY::Clean_name(nameScale)), + fNB(UTILITY::Clean_name(nameB)), fNMean(UTILITY::Clean_name(nameMean)), + fNVar(UTILITY::Clean_name(nameVar)), fNY(UTILITY::Clean_name(nameY)) + { + if(std::is_same::value){ + fType = "float"; + } + else{ + throw + std::runtime_error("TMVA SOFIE Encountered unsupported type parsing a BatchNormalization operator"); + } + } - std::vector TypeInference(std::vector input) { - ETensorType out = input[0]; - return {out}; - } - - std::vector> ShapeInference(std::vector> input) { - if (input.size() != 5 ) { - throw - std::runtime_error("TMVA SOFIE BatchNormalization Op Shape inference need 5 input tensors"); - } - for(size_t i = 0; i < input.size(); i++) { - if (input[i].size() != 4) { - throw - std::runtime_error("TMVA SOFIE BatchNormalization Op Shape inference only accept tensor with 4 dimensions"); - } - } - - auto ret = input; - return ret; - } - - void Initialize(RModel& model){ - if (!model.CheckIfTensorAlreadyExist(fNX)) { - throw - std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNX + " fnx is not found in model"); - } - if (!model.CheckIfTensorAlreadyExist(fNScale)) { - throw - std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNScale + " fns is not found in model"); - } - if (!model.CheckIfTensorAlreadyExist(fNB)) { - throw - std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNB + " fnb is not found in model"); - } - if (!model.CheckIfTensorAlreadyExist(fNMean)) { - throw - std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNMean + " fnm is not found in model"); - } - if (!model.CheckIfTensorAlreadyExist(fNVar)) { - throw - std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNVar + " fnv is not found in model"); - } - - fShapeX = model.GetTensorShape(fNX); - + std::vector TypeInference(std::vector input) { + ETensorType out = input[0]; + return {out}; + } + + std::vector> ShapeInference(std::vector> input) { + if (input.size() != 5 ) { + throw + std::runtime_error("TMVA SOFIE BatchNormalization Op Shape inference need 5 input tensors"); + } + for(size_t i = 0; i < input.size(); i++) { + if (input[i].size() != 4) { + throw + std::runtime_error("TMVA SOFIE BatchNormalization Op Shape inference only accept tensor with 4 dimensions"); + } + } + + auto ret = input; + return ret; + } + + void Initialize(RModel& model){ + if (!model.CheckIfTensorAlreadyExist(fNX)) { + throw + std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNX + " fnx is not found in model"); + } + if (!model.CheckIfTensorAlreadyExist(fNScale)) { + throw + std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNScale + " fns is not found in model"); + } + if (!model.CheckIfTensorAlreadyExist(fNB)) { + throw + std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNB + " fnb is not found in model"); + } + if (!model.CheckIfTensorAlreadyExist(fNMean)) { + throw + std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNMean + " fnm is not found in model"); + } + if (!model.CheckIfTensorAlreadyExist(fNVar)) { + throw + std::runtime_error("TMVA SOFIE BatchNormalization op Input Tensor " + fNVar + " fnv is not found in model"); + } + + fShapeX = model.GetTensorShape(fNX); + if (fShapeX.size() < 2 || fShapeX.size() > 4) { throw - std::runtime_error("TMVA SOFIE BatchNormalization Op input tensor " + fNX + " fnx has wrong shape : " + ConvertShapeToString(fShapeX)); + std::runtime_error("TMVA SOFIE BatchNormalization Op input tensor " + fNX + " fnx has wrong shape : " + ConvertShapeToString(fShapeX)); } fShapeScale = model.GetTensorShape(fNScale); - fShapeB = model.GetTensorShape(fNB); - fShapeMean = model.GetTensorShape(fNMean); - fShapeVar = model.GetTensorShape(fNVar); - fShapeY = fShapeX; - model.AddIntermediateTensor(fNY, model.GetTensorType(fNX), fShapeY); - - if (fShapeB.size() == 1) { - // Broadcast scale, bias, input_mean and input_var to shape_X - auto original_B = model.GetInitializedTensorData(fNB); - auto original_S = model.GetInitializedTensorData(fNScale); - auto original_M = model.GetInitializedTensorData(fNMean); - auto original_V = model.GetInitializedTensorData(fNVar); - size_t batchSize = fShapeX[0]; - size_t channels = fShapeX[1]; - size_t height = (fShapeX.size() > 2) ? fShapeX[2] : 1; - size_t width = (fShapeX.size() > 3) ? fShapeX[3] : 1; - size_t n = batchSize * channels * height * width; + fShapeB = model.GetTensorShape(fNB); + fShapeMean = model.GetTensorShape(fNMean); + fShapeVar = model.GetTensorShape(fNVar); + fShapeY = fShapeX; + model.AddIntermediateTensor(fNY, model.GetTensorType(fNX), fShapeY); + + if (fShapeB.size() == 1) { + // Broadcast scale, bias, input_mean and input_var to shape_X + auto original_B = model.GetInitializedTensorData(fNB); + auto original_S = model.GetInitializedTensorData(fNScale); + auto original_M = model.GetInitializedTensorData(fNMean); + auto original_V = model.GetInitializedTensorData(fNVar); + size_t batchSize = fShapeX[0]; + size_t channels = fShapeX[1]; + size_t height = (fShapeX.size() > 2) ? fShapeX[2] : 1; + size_t width = (fShapeX.size() > 3) ? fShapeX[3] : 1; + size_t n = batchSize * channels * height * width; if (fType == "float") { - float *original_bias = static_cast(original_B.get()); - float *original_scale = static_cast(original_S.get()); - float *original_mean = static_cast(original_M.get()); - float *original_var = static_cast(original_V.get()); - float *new_bias = new float[n]; - float *new_scale = new float[n]; - float *new_mean = new float[n]; - float *new_var = new float[n]; - size_t bs = 0, ch = 0, h = 0, w = 0; - for(ch=0; ch new_bias_shape = {batchSize,channels,height,width}; - std::shared_ptr new_bias_ptr(new_bias, std::default_delete()); - std::shared_ptr new_scale_ptr(new_scale, std::default_delete()); - std::shared_ptr new_mean_ptr(new_mean, std::default_delete()); - std::shared_ptr new_var_ptr(new_var, std::default_delete()); - model.UpdateInitializedTensor(fNB, model.GetTensorType(fNB), new_bias_shape, new_bias_ptr); - model.UpdateInitializedTensor(fNScale, model.GetTensorType(fNScale), new_bias_shape, new_scale_ptr); - model.UpdateInitializedTensor(fNMean, model.GetTensorType(fNMean), new_bias_shape, new_mean_ptr); - model.UpdateInitializedTensor(fNVar, model.GetTensorType(fNVar), new_bias_shape, new_var_ptr); - fShapeB = model.GetTensorShape(fNB); - fShapeScale = model.GetTensorShape(fNScale); - fShapeMean = model.GetTensorShape(fNMean); - fShapeVar = model.GetTensorShape(fNVar); + float *original_bias = static_cast(original_B.get()); + float *original_scale = static_cast(original_S.get()); + float *original_mean = static_cast(original_M.get()); + float *original_var = static_cast(original_V.get()); + float *new_bias = new float[n]; + float *new_scale = new float[n]; + float *new_mean = new float[n]; + float *new_var = new float[n]; + size_t bs = 0, ch = 0, h = 0, w = 0; + for(ch=0; ch new_bias_shape = {batchSize,channels,height,width}; + std::shared_ptr new_bias_ptr(new_bias, std::default_delete()); + std::shared_ptr new_scale_ptr(new_scale, std::default_delete()); + std::shared_ptr new_mean_ptr(new_mean, std::default_delete()); + std::shared_ptr new_var_ptr(new_var, std::default_delete()); + model.UpdateInitializedTensor(fNB, model.GetTensorType(fNB), new_bias_shape, new_bias_ptr); + model.UpdateInitializedTensor(fNScale, model.GetTensorType(fNScale), new_bias_shape, new_scale_ptr); + model.UpdateInitializedTensor(fNMean, model.GetTensorType(fNMean), new_bias_shape, new_mean_ptr); + model.UpdateInitializedTensor(fNVar, model.GetTensorType(fNVar), new_bias_shape, new_var_ptr); + fShapeB = model.GetTensorShape(fNB); + fShapeScale = model.GetTensorShape(fNScale); + fShapeMean = model.GetTensorShape(fNMean); + fShapeVar = model.GetTensorShape(fNVar); } - } - } + } + } - std::string Generate(std::string OpName){ - OpName = "op_" + OpName; - if (fShapeX.empty()){ - throw std::runtime_error("TMVA SOFIE Batch Normalization called to Generate without being initialized first"); - } + std::string Generate(std::string OpName){ + OpName = "op_" + OpName; + if (fShapeX.empty()){ + throw std::runtime_error("TMVA SOFIE Batch Normalization called to Generate without being initialized first"); + } - std::stringstream out; - //// Batch Norm op + std::stringstream out; + //// Batch Norm op size_t batchSize = fShapeX[0]; size_t channels = fShapeX[1]; size_t height = (fShapeX.size() > 2) ? fShapeX[2] : 1; size_t width = (fShapeX.size() > 3) ? fShapeX[3] : 1; size_t n = batchSize * channels * height * width; - //// copy X into Y + //// copy X into Y out << SP << "constexpr int " << OpName << "_N =" << batchSize * channels * height * width << ";\n"; out << SP << "constexpr int "<> ShapeInference(std::vector> input) { - // shape of convolution input has to be (according to ONNX): NxCxHxW - // Where N is batch size, C : input channels, H : input height, W = input width + // shape of convolution input has to be (according to ONNX): N x C x H x W + // Where N : batch size, C : input channels, H : input height, W : input width if (input.size() > 3 ) { throw @@ -139,7 +139,7 @@ public: else if (fDim == 3) fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[2] / 2, fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[2] / 2}; - // add extra padding at beginnig or end (depending if SAME_UPPER or SAME_LOWER) + // add extra padding at beginning or end (depending if SAME_UPPER or SAME_LOWER) // need to check this! if (fAttrKernelShape[0] % 2 == 1) { (fAttrAutopad == "SAME_UPPER") ? fAttrPads[0]++ : fAttrPads[i1]++; @@ -174,7 +174,7 @@ public: size_t batch_size = input[0][0]; // first element in input tensor size_t output_channels = input[1][0]; // first element in weight tensor - std::vector> ret({{batch_size, output_channels, output1 }}); + std::vector> ret({{ batch_size, output_channels, output1 }}); if (fDim == 1) return ret; @@ -238,7 +238,7 @@ public: if (fType != "float") throw std::runtime_error("TMVA SOFIE Conv op: Broadcasting for non-float type tensors is not supported"); - // here the acual broadcasting + // here is the actual broadcasting if (!fUseSession) { fShapeB.resize(fShapeY.size(), 1.); @@ -263,7 +263,7 @@ public: std::string GenerateInitCode() { size_t oDepth = (fDim > 2) ? fShapeY[2] : 1; // output depth - size_t oHeight = (fDim > 1) ? fShapeY[fDim] : 1; // ouput height + size_t oHeight = (fDim > 1) ? fShapeY[fDim] : 1; // output height size_t oWidth = fShapeY[fDim+1]; // output width std::stringstream out; @@ -282,7 +282,7 @@ public: out << " float * newData_ptr = TMVA::Experimental::SOFIE::UTILITY::Unidirectional_broadcast(" << original_bias_tensor << ", oldShape, newShape);\n"; // extend the new broadcasted bias tensor for the batch dimension - int length = fShapeY[1]*oDepth*oHeight*oWidth; // output nc*h*w + int length = fShapeY[1]*oDepth*oHeight*oWidth; // output N X C X H X W out << " for (int i = 0; i < " << fShapeY[0] << " ; i++)\n"; out << " std::copy(newData_ptr, newData_ptr + " << length << ", " << new_bias_tensor << " + i * " << length << ");\n"; @@ -295,7 +295,7 @@ public: // generate code for Session data members (e.g. internal vectors) virtual std::string GenerateSessionMembersCode(std::string opName) { - size_t outputChannelSize = fShapeY[2]; // size/chanhel = D * H * W + size_t outputChannelSize = fShapeY[2]; // size/channel = D * H * W size_t kernelSize = fAttrKernelShape[0]; for (size_t i = 1; i < fDim; i++) { outputChannelSize *= fShapeY[2 + i]; @@ -441,7 +441,7 @@ public: if (fAttrGroup == 1) { out << SP << SP << "size_t x_offset = n * " << fShapeX[1] * iHeight * iWidth << ";\n"; out << SP << SP << "size_t out_offset = n * " << fShapeY[1] * oHeight * oWidth << ";\n"; - // when using im2col - resulting matrix is transposed, is (input_c * filter_h * filter_y, output_h * + // when using im2col - resulting matrix is transposed, the dimension is (input_c * filter_h * filter_y, output_h * // output_w) if (fDim < 3) { out << SP << SP << "TMVA::Experimental::SOFIE::UTILITY::Im2col(tensor_" << fNX diff --git a/tmva/sofie/inc/TMVA/ROperator_Gemm.hxx b/tmva/sofie/inc/TMVA/ROperator_Gemm.hxx index 24c4b0a8759e4..71ff8de1d63f9 100644 --- a/tmva/sofie/inc/TMVA/ROperator_Gemm.hxx +++ b/tmva/sofie/inc/TMVA/ROperator_Gemm.hxx @@ -207,7 +207,7 @@ namespace SOFIE{ if (fNC != ""){ size_t length = ConvertShapeToLength(fShapeY); if (fNC2 == fNC) - // case broadcasting was not needed or done otside of session + // case broadcasting was not needed or done outside of session assert(length == ConvertShapeToLength(fShapeC)); out << SP << "std::copy(" << "tensor_" << fNC2 << ", " << "tensor_" << fNC2 << " + " << length << ", " << "tensor_" << fNY << ");\n"; } diff --git a/tmva/sofie/inc/TMVA/ROperator_Reshape.hxx b/tmva/sofie/inc/TMVA/ROperator_Reshape.hxx index ccc5c03e311c6..d45e6a08f2a10 100644 --- a/tmva/sofie/inc/TMVA/ROperator_Reshape.hxx +++ b/tmva/sofie/inc/TMVA/ROperator_Reshape.hxx @@ -43,7 +43,7 @@ public: } // for squeeze/unsqueezed operators following old ONNX version (< 10) - // IN this cases axes are passed as attribute values + // In this cases axes are passed as attribute values ROperator_Reshape(ReshapeOpMode opMode, std::vector attrAxes, std::string nameData, std::string nameOutput) : fOpMode(opMode), fNData(UTILITY::Clean_name(nameData)), fNOutput(UTILITY::Clean_name(nameOutput)), fAttrAxes(attrAxes) @@ -67,7 +67,7 @@ public: auto output_shape = input[1]; // the provided shape size_t input_length = ConvertShapeToLength(input_shape); size_t output_length = ConvertShapeToLength(output_shape); - // input_length == output_length) is the easy case : (2,3,4) -> (2,12) + // (input_length == output_length) is the easy case : (2,3,4) -> (2,12) if (input_length != output_length) { if (output_shape.size() > 1 && ((output_length == 0 && fAllowZero == 0) || output_length > INT64_MAX)) { // in this case value 0 in shape are automatically corrected diff --git a/tmva/sofie/inc/TMVA/ROperator_Slice.hxx b/tmva/sofie/inc/TMVA/ROperator_Slice.hxx index 84341ec4ec8e2..c6496f291c2c2 100644 --- a/tmva/sofie/inc/TMVA/ROperator_Slice.hxx +++ b/tmva/sofie/inc/TMVA/ROperator_Slice.hxx @@ -30,7 +30,7 @@ private: std::vector fEnd; // End values of slices std::vector fSteps; // step values of slices - std::vector> fAttributes; // attributes for theversion <=10 case + std::vector> fAttributes; // attributes for the version <=10 case public: From f799ed3455e570beb052c3104ae36b8c1b7f9ae4 Mon Sep 17 00:00:00 2001 From: Neel-Shah-29 Date: Thu, 30 Jun 2022 16:32:47 +0530 Subject: [PATCH 102/104] All the four Binary Operators:- Add,Sub,Mul,Div added with the corresponding unit tests and Multi-directional broadcasting functionality is added for SOFIE --- tmva/sofie/CMakeLists.txt | 2 +- tmva/sofie/inc/TMVA/OperatorList.hxx | 2 +- tmva/sofie/inc/TMVA/ROperator_Add.hxx | 88 ----------- tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx | 128 +++++++++++++++ tmva/sofie/inc/TMVA/SOFIE_common.hxx | 1 + tmva/sofie/src/SOFIE_common.cxx | 43 ++++++ tmva/sofie/test/TestCustomModelsFromONNX.cxx | 146 ++++++++++++++++++ tmva/sofie/test/input_models/Add.onnx | 16 ++ .../test/input_models/Add_broadcast.onnx | 18 +++ tmva/sofie/test/input_models/Div.onnx | 16 ++ tmva/sofie/test/input_models/Mul.onnx | 16 ++ tmva/sofie/test/input_models/Sub.onnx | 16 ++ .../test/input_models/references/Add.ref.hxx | 5 + .../references/Add_broadcast.ref.hxx | 6 + .../test/input_models/references/Div.ref.hxx | 5 + .../test/input_models/references/Mul.ref.hxx | 5 + .../test/input_models/references/Sub.ref.hxx | 5 + .../inc/TMVA/RModelParser_ONNX.hxx | 8 +- tmva/sofie_parsers/src/RModelParser_ONNX.cxx | 41 +++-- 19 files changed, 460 insertions(+), 107 deletions(-) delete mode 100644 tmva/sofie/inc/TMVA/ROperator_Add.hxx create mode 100644 tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx create mode 100644 tmva/sofie/test/input_models/Add.onnx create mode 100644 tmva/sofie/test/input_models/Add_broadcast.onnx create mode 100644 tmva/sofie/test/input_models/Div.onnx create mode 100644 tmva/sofie/test/input_models/Mul.onnx create mode 100644 tmva/sofie/test/input_models/Sub.onnx create mode 100644 tmva/sofie/test/input_models/references/Add.ref.hxx create mode 100644 tmva/sofie/test/input_models/references/Add_broadcast.ref.hxx create mode 100644 tmva/sofie/test/input_models/references/Div.ref.hxx create mode 100644 tmva/sofie/test/input_models/references/Mul.ref.hxx create mode 100644 tmva/sofie/test/input_models/references/Sub.ref.hxx diff --git a/tmva/sofie/CMakeLists.txt b/tmva/sofie/CMakeLists.txt index 5378a27ff419a..1fefffc99b639 100644 --- a/tmva/sofie/CMakeLists.txt +++ b/tmva/sofie/CMakeLists.txt @@ -16,7 +16,7 @@ ROOT_STANDARD_LIBRARY_PACKAGE(ROOTTMVASofie TMVA/OperatorList.hxx TMVA/RModel.hxx TMVA/ROperator.hxx - TMVA/ROperator_Add.hxx + TMVA/ROperator_BasicBinary.hxx TMVA/ROperator_BatchNormalization.hxx TMVA/ROperator_Conv.hxx TMVA/ROperator_Gemm.hxx diff --git a/tmva/sofie/inc/TMVA/OperatorList.hxx b/tmva/sofie/inc/TMVA/OperatorList.hxx index 09222c18f02a2..179cfdac4af39 100644 --- a/tmva/sofie/inc/TMVA/OperatorList.hxx +++ b/tmva/sofie/inc/TMVA/OperatorList.hxx @@ -9,7 +9,7 @@ #include "TMVA/ROperator_LSTM.hxx" #include "TMVA/ROperator_BatchNormalization.hxx" #include "TMVA/ROperator_Pool.hxx" -#include "TMVA/ROperator_Add.hxx" +#include "TMVA/ROperator_BasicBinary.hxx" #include "TMVA/ROperator_Reshape.hxx" #include "TMVA/ROperator_Slice.hxx" #include "TMVA/ROperator_GRU.hxx" diff --git a/tmva/sofie/inc/TMVA/ROperator_Add.hxx b/tmva/sofie/inc/TMVA/ROperator_Add.hxx deleted file mode 100644 index adaed3ea68ef4..0000000000000 --- a/tmva/sofie/inc/TMVA/ROperator_Add.hxx +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef TMVA_SOFIE_ROPERATOR_ADD -#define TMVA_SOFIE_ROPERATOR_ADD - -#include "TMVA/SOFIE_common.hxx" -#include "TMVA/ROperator.hxx" -#include "TMVA/RModel.hxx" - -#include - -namespace TMVA{ -namespace Experimental{ -namespace SOFIE{ - -template -class ROperator_Add final : public ROperator -{ - -private: - - std::string fNX1; - std::string fNX2; - std::string fNY; - std::vector fShape; - -public: - ROperator_Add(){} - ROperator_Add(std::string nameX1, std::string nameX2, std::string nameY): - fNX1(UTILITY::Clean_name(nameX1)), fNX2(UTILITY::Clean_name(nameX2)), fNY(UTILITY::Clean_name(nameY)){} - - // type of output given input - std::vector TypeInference(std::vector input){ - return input; - } - - // shape of output tensors given input tensors - std::vector> ShapeInference(std::vector> input){ - // assume now inputs have same shape (no broadcasting) - auto ret = std::vector>(1, input[0]); // return vector size 1 with first input - return ret; - } - - void Initialize(RModel& model){ - // input must be a graph input, or already initialized intermediate tensor - if (model.CheckIfTensorAlreadyExist(fNX1) == false){ - throw std::runtime_error(std::string("TMVA SOFIE Add Op Input Tensor ") + fNX1 + "is not found in model"); - } - if (model.CheckIfTensorAlreadyExist(fNX2) == false) { - throw std::runtime_error(std::string("TMVA SOFIE Add Op Input Tensor ") + fNX2 + "is not found in model"); - } - auto shapeX1 = model.GetTensorShape(fNX1); - auto shapeX2 = model.GetTensorShape(fNX2); - // assume same shape X1 and X2 - if (shapeX1 != shapeX2) { - std::string msg = "TMVA SOFIE Add Op: Support only inputs with same shape, shape 1 is " + - ConvertShapeToString(shapeX1) + "and shape 2 is " + ConvertShapeToString(shapeX2); - throw std::runtime_error(msg); - } - fShape = shapeX1; - model.AddIntermediateTensor(fNY, model.GetTensorType(fNX1), fShape); - } - - - std::string Generate(std::string OpName){ - OpName = "op_" + OpName; - if (fShape.empty()) { - throw std::runtime_error("TMVA SOFIE Add called to Generate without being initialized first"); - } - std::stringstream out; - // int length = 1; - // for(auto& i: fShape){ - // length *= i; - // } - size_t length = ConvertShapeToLength(fShape); - out << "\n//------ Add\n"; - out << SP << "for (size_t id = 0; id < " << length << " ; id++){\n"; - out << SP << SP << "tensor_" << fNY << "[id] = tensor_" << fNX1 << "[id] + tensor_" << fNX2 << "[id];\n"; - out << SP << "}\n"; - return out.str(); - } - -}; - -}//SOFIE -}//Experimental -}//TMVA - - -#endif //TMVA_SOFIE_ROPERATOR_Add diff --git a/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx b/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx new file mode 100644 index 0000000000000..4a26526b113e7 --- /dev/null +++ b/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx @@ -0,0 +1,128 @@ +#ifndef TMVA_SOFIE_ROperator_BasicBinary +#define TMVA_SOFIE_ROperator_BasicBinary + +#include "TMVA/SOFIE_common.hxx" +#include "TMVA/ROperator.hxx" +#include "TMVA/RModel.hxx" + +#include + +namespace TMVA{ +namespace Experimental{ +namespace SOFIE{ + +enum EBasicBinaryOperator { Add, Sub, Mul, Div }; + +template +struct BinaryOperatorTrait { + const char *Name() { return ""; } + const char *Op() { return ""; } +}; +template +struct BinaryOperatorTrait { + static const char *Name() { return "Add"; } + static const char *Op() { return "+"; } +}; + +template +struct BinaryOperatorTrait { + static const char *Name() { return "Sub"; } + static const char *Op() { return "-"; } +}; + +template +struct BinaryOperatorTrait { + static const char *Name() { return "Mul"; } + static const char *Op() { return "*"; } +}; + +template +struct BinaryOperatorTrait { + static const char *Name() { return "Div"; } + static const char *Op() { return "/"; } +}; + +template +class ROperator_BasicBinary final : public ROperator{ +private: + + std::string fNX1; + std::string fNX2; + std::string fNY; + std::vector fShape; + + // template + // BinaryOperatorTrait *s; + +public: + ROperator_BasicBinary(){} + ROperator_BasicBinary(std::string nameX1, std::string nameX2, std::string nameY): + fNX1(UTILITY::Clean_name(nameX1)), fNX2(UTILITY::Clean_name(nameX2)), fNY(UTILITY::Clean_name(nameY)){} + + // type of output given input + std::vector TypeInference(std::vector input){ + return input; + } + + // shape of output tensors given input tensors + std::vector> ShapeInference(std::vector> input){ + // assume now inputs have same shape (no broadcasting) + auto ret = std::vector>(1, input[0]); // return vector size 1 with first input + return ret; + } + + void Initialize(RModel& model){ + // input must be a graph input, or already initialized intermediate tensor + if (model.CheckIfTensorAlreadyExist(fNX1) == false){ + throw std::runtime_error(std::string("TMVA SOFIE Binary Op Input Tensor ") + fNX1 + "is not found in model"); + } + if (model.CheckIfTensorAlreadyExist(fNX2) == false) { + throw std::runtime_error(std::string("TMVA SOFIE Binary Op Input Tensor ") + fNX2 + "is not found in model"); + } + auto shapeX1 = model.GetTensorShape(fNX1); + auto shapeX2 = model.GetTensorShape(fNX2); + // assume same shape X1 and X2 + if (shapeX1 != shapeX2) { + fShape = UTILITY::Multidirectional_broadcast(shapeX1,shapeX2); + size_t length1 = ConvertShapeToLength(shapeX1); + size_t length2 = ConvertShapeToLength(shapeX2); + size_t output_length = ConvertShapeToLength(fShape); + if(length1 != length2 || length1 != output_length){ + throw std::runtime_error(std::string("TMVA SOFIE Binary Op does not support input tensors with different lengths. The output tensor should also have the same length as the input tensors.")); + } + } + else if(shapeX1 == shapeX2){ + fShape = shapeX1; + } + model.AddIntermediateTensor(fNY, model.GetTensorType(fNX1), fShape); + } + + + std::string Generate(std::string OpName){ + OpName = "op_" + OpName; + + if (fShape.empty()) { + throw std::runtime_error("TMVA SOFIE Binary Op called to Generate without being initialized first"); + } + std::stringstream out; + // int length = 1; + // for(auto& i: fShape){ + // length *= i; + // } + size_t length = ConvertShapeToLength(fShape); + out << "\n//------ " + std::string(BinaryOperatorTrait::Name())+"\n"; + out << SP << "for (size_t id = 0; id < " << length << " ; id++){\n"; + out << SP << SP << "tensor_" << fNY << "[id] = tensor_" << fNX1 << "[id]" + + std::string(BinaryOperatorTrait::Op()) + "tensor_" << fNX2 << "[id];\n"; + out << SP << "}\n"; + return out.str(); + } + +}; + +}//SOFIE +}//Experimental +}//TMVA + + +#endif //TMVA_SOFIE_ROperator_BasicBinary \ No newline at end of file diff --git a/tmva/sofie/inc/TMVA/SOFIE_common.hxx b/tmva/sofie/inc/TMVA/SOFIE_common.hxx index 7876727eef0ae..6f72b27104c5a 100644 --- a/tmva/sofie/inc/TMVA/SOFIE_common.hxx +++ b/tmva/sofie/inc/TMVA/SOFIE_common.hxx @@ -105,6 +105,7 @@ ETensorType GetTemplatedType(T /*obj*/ ){ namespace UTILITY{ template T* Unidirectional_broadcast(const T* original_data, const std::vector original_shape, const std::vector target_shape); +std::vector Multidirectional_broadcast(const std::vector input1_shape, const std::vector input2_shape); std::string Clean_name(std::string input_tensor_name); diff --git a/tmva/sofie/src/SOFIE_common.cxx b/tmva/sofie/src/SOFIE_common.cxx index 78feff703cb48..6874a9b5d0502 100644 --- a/tmva/sofie/src/SOFIE_common.cxx +++ b/tmva/sofie/src/SOFIE_common.cxx @@ -135,6 +135,49 @@ T* UTILITY::Unidirectional_broadcast(const T* original_data, const std::vector UTILITY::Multidirectional_broadcast(std::vector input1_shape, std::vector input2_shape) +{ + std::vector input_shape = (input1_shape.size() > input2_shape.size())?input1_shape:input2_shape; + std::vector output_shape(input_shape); + + if(input1_shape.size() < input2_shape.size()){ + // Check if input1_shape.size() < input2_shape.size() we insert in the shape vector values of 1 at the beginning of the tensor until input1_shape.size() == input2_shape.size() + auto it = input1_shape.begin(); + while (input1_shape.size() < input2_shape.size()) { + it = input1_shape.insert(it, 1); + } + } + else if(input2_shape.size() < input1_shape.size()){ + // Check if input2_shape.size() < input1_shape.size() we insert in the shape vector values of 1 at the beginning of the tensor until input1_shape.size() == input2_shape.size() + auto it = input2_shape.begin(); + while (input2_shape.size() < input1_shape.size()) { + it = input2_shape.insert(it, 1); + } + } + //check if both the input have same shape, nothing to do directly return the output_shape as the same shape. + if(input1_shape.size() == input2_shape.size()){ + if(input1_shape != input2_shape){ + //Check the shape values, if input1[i] not equal to input2[i] we have the result shape equal to input1[i] if input2[i] = 1 or viceversa + for(size_t j = 0; j < input1_shape.size() ; j++){ + if(input1_shape[j] == input2_shape[j]){ + output_shape[j] = input1_shape[j]; + } + else if(input1_shape[j] > input2_shape[j] && input2_shape[j] == 1){ + output_shape[j] = input1_shape[j]; + } + else if(input2_shape[j] > input1_shape[j] && input1_shape[j] == 1){ + output_shape[j] = input2_shape[j]; + } + } + } + + } + return output_shape; + +} + std::string UTILITY::Clean_name(std::string input_tensor_name){ std::string s (input_tensor_name); s.erase(std::remove_if(s.begin(), s.end(), []( char const& c ) -> bool { return !std::isalnum(c); } ), s.end()); diff --git a/tmva/sofie/test/TestCustomModelsFromONNX.cxx b/tmva/sofie/test/TestCustomModelsFromONNX.cxx index 6da224fc641e2..757d81e70a00b 100644 --- a/tmva/sofie/test/TestCustomModelsFromONNX.cxx +++ b/tmva/sofie/test/TestCustomModelsFromONNX.cxx @@ -12,6 +12,21 @@ #include "LinearWithSelu_FromONNX.hxx" #include "input_models/references/LinearWithSelu.ref.hxx" +#include "Sub_FromONNX.hxx" +#include "input_models/references/Sub.ref.hxx" + +#include "Add_FromONNX.hxx" +#include "input_models/references/Add.ref.hxx" + +#include "Add_broadcast_FromONNX.hxx" +#include "input_models/references/Add_broadcast.ref.hxx" + +#include "Mul_FromONNX.hxx" +#include "input_models/references/Mul.ref.hxx" + +#include "Div_FromONNX.hxx" +#include "input_models/references/Div.ref.hxx" + #include "LinearWithLeakyRelu_FromONNX.hxx" #include "input_models/references/LinearWithLeakyRelu.ref.hxx" @@ -146,6 +161,137 @@ TEST(ONNX, Linear32) } } +TEST(ONNX, Sub) + { + constexpr float TOLERANCE = DEFAULT_TOLERANCE; + + // Preparing the standard input + std::vector input1({ + 1, 2 + }); + std::vector input2({ + 0, 1 + }); + TMVA_SOFIE_Sub::Session s("Sub_FromONNX.dat"); + + std::vector output = s.infer(input2.data(),input1.data()); + + // Checking output size + EXPECT_EQ(output.size(), sizeof(Sub_ExpectedOutput::outputs) / sizeof(float)); + + float *correct = Sub_ExpectedOutput::outputs; + + // Checking every output value, one by one + for (size_t i = 0; i < output.size(); ++i) { + EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); + } + } + +TEST(ONNX, Add_broadcast) + { + constexpr float TOLERANCE = DEFAULT_TOLERANCE; + + // Preparing the standard input + std::vector input1({ + 1, 2, 3, + 3, 4, 5 + }); + std::vector input2({ + 5, 6, 7, + 8, 9, 10 + }); + TMVA_SOFIE_Add_broadcast::Session s("Add_broadcast_FromONNX.dat"); + + std::vector output = s.infer(input2.data(),input1.data()); + + // Checking output size + EXPECT_EQ(output.size(), sizeof(Add_broadcast_ExpectedOutput::outputs) / sizeof(float)); + + float *correct = Add_broadcast_ExpectedOutput::outputs; + + // Checking every output value, one by one + for (size_t i = 0; i < output.size(); ++i) { + EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); + } + } + +TEST(ONNX, Add) + { + constexpr float TOLERANCE = DEFAULT_TOLERANCE; + + // Preparing the standard input + std::vector input1({ + 1, 2 + }); + std::vector input2({ + 0, 1 + }); + TMVA_SOFIE_Add::Session s("Add_FromONNX.dat"); + + std::vector output = s.infer(input1.data(),input2.data()); + + // Checking output size + EXPECT_EQ(output.size(), sizeof(Add_ExpectedOutput::outputs) / sizeof(float)); + + float *correct = Add_ExpectedOutput::outputs; + + // Checking every output value, one by one + for (size_t i = 0; i < output.size(); ++i) { + EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); + } + } + +TEST(ONNX, Mul) + { + constexpr float TOLERANCE = DEFAULT_TOLERANCE; + + // Preparing the standard input + std::vector input1({ + 1, 2 + }); + std::vector input2({ + 0, 1 + }); + TMVA_SOFIE_Mul::Session s("Mul_FromONNX.dat"); + + std::vector output = s.infer(input1.data(),input2.data()); + + // Checking output size + EXPECT_EQ(output.size(), sizeof(Mul_ExpectedOutput::outputs) / sizeof(float)); + + float *correct = Mul_ExpectedOutput::outputs; + + // Checking every output value, one by one + for (size_t i = 0; i < output.size(); ++i) { + EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); + } + } + +TEST(ONNX, Div) + { + constexpr float TOLERANCE = DEFAULT_TOLERANCE; + + // Preparing the standard input + std::vector input1({ + 4, 2 + }); + std::vector input2({ + 2, 2 + }); + TMVA_SOFIE_Div::Session s("Div_FromONNX.dat"); + + std::vector output = s.infer(input2.data(),input1.data()); + + // Checking output size + EXPECT_EQ(output.size(), sizeof(Div_ExpectedOutput::outputs) / sizeof(float)); + + float *correct = Div_ExpectedOutput::outputs; + + // Checking every output value, one by one + for (size_t i = 0; i < output.size(); ++i) { + EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); + } + } TEST(ONNX, Linear64) { diff --git a/tmva/sofie/test/input_models/Add.onnx b/tmva/sofie/test/input_models/Add.onnx new file mode 100644 index 0000000000000..c1773f247ae7e --- /dev/null +++ b/tmva/sofie/test/input_models/Add.onnx @@ -0,0 +1,16 @@ +pytorch1.11.0:„ +) + onnx::Add_0 + onnx::Add_12Add_0"Addtorch-jit-exportZ + onnx::Add_0 + + +Z + onnx::Add_1 + + +b +2 + + +B \ No newline at end of file diff --git a/tmva/sofie/test/input_models/Add_broadcast.onnx b/tmva/sofie/test/input_models/Add_broadcast.onnx new file mode 100644 index 0000000000000..34c79e3087172 --- /dev/null +++ b/tmva/sofie/test/input_models/Add_broadcast.onnx @@ -0,0 +1,18 @@ +pytorch1.11.0:˜ +) + onnx::Add_0 + onnx::Add_12Add_0"Addtorch-jit-exportZ! + onnx::Add_0 + + + +Z + onnx::Add_1 +  + +b +2 + + + +B \ No newline at end of file diff --git a/tmva/sofie/test/input_models/Div.onnx b/tmva/sofie/test/input_models/Div.onnx new file mode 100644 index 0000000000000..c76721b368f48 --- /dev/null +++ b/tmva/sofie/test/input_models/Div.onnx @@ -0,0 +1,16 @@ +pytorch1.11.0:„ +) + onnx::Div_0 + onnx::Div_12Div_0"Divtorch-jit-exportZ + onnx::Div_0 + + +Z + onnx::Div_1 + + +b +2 + + +B \ No newline at end of file diff --git a/tmva/sofie/test/input_models/Mul.onnx b/tmva/sofie/test/input_models/Mul.onnx new file mode 100644 index 0000000000000..2f68a047d5762 --- /dev/null +++ b/tmva/sofie/test/input_models/Mul.onnx @@ -0,0 +1,16 @@ +pytorch1.11.0:„ +) + onnx::Mul_0 + onnx::Mul_12Mul_0"Multorch-jit-exportZ + onnx::Mul_0 + + +Z + onnx::Mul_1 + + +b +2 + + +B \ No newline at end of file diff --git a/tmva/sofie/test/input_models/Sub.onnx b/tmva/sofie/test/input_models/Sub.onnx new file mode 100644 index 0000000000000..3b86b93723c14 --- /dev/null +++ b/tmva/sofie/test/input_models/Sub.onnx @@ -0,0 +1,16 @@ +pytorch1.11.0:„ +) + onnx::Sub_0 + onnx::Sub_12Sub_0"Subtorch-jit-exportZ + onnx::Sub_0 + + +Z + onnx::Sub_1 + + +b +2 + + +B \ No newline at end of file diff --git a/tmva/sofie/test/input_models/references/Add.ref.hxx b/tmva/sofie/test/input_models/references/Add.ref.hxx new file mode 100644 index 0000000000000..9822c7a81c9a8 --- /dev/null +++ b/tmva/sofie/test/input_models/references/Add.ref.hxx @@ -0,0 +1,5 @@ +namespace Add_ExpectedOutput{ + float outputs[] = { + 1, 3 + }; +} // namespace Add_ExpectedOutput \ No newline at end of file diff --git a/tmva/sofie/test/input_models/references/Add_broadcast.ref.hxx b/tmva/sofie/test/input_models/references/Add_broadcast.ref.hxx new file mode 100644 index 0000000000000..10b1d385ff1dd --- /dev/null +++ b/tmva/sofie/test/input_models/references/Add_broadcast.ref.hxx @@ -0,0 +1,6 @@ +namespace Add_broadcast_ExpectedOutput{ + float outputs[] = { + 6, 8, 10, + 11, 13, 15 + }; +} // namespace Add_ExpectedOutput \ No newline at end of file diff --git a/tmva/sofie/test/input_models/references/Div.ref.hxx b/tmva/sofie/test/input_models/references/Div.ref.hxx new file mode 100644 index 0000000000000..ad2859637cfb2 --- /dev/null +++ b/tmva/sofie/test/input_models/references/Div.ref.hxx @@ -0,0 +1,5 @@ +namespace Div_ExpectedOutput{ + float outputs[] = { + 2, 1 + }; +} // namespace Div_ExpectedOutput \ No newline at end of file diff --git a/tmva/sofie/test/input_models/references/Mul.ref.hxx b/tmva/sofie/test/input_models/references/Mul.ref.hxx new file mode 100644 index 0000000000000..465bf1b57bf7e --- /dev/null +++ b/tmva/sofie/test/input_models/references/Mul.ref.hxx @@ -0,0 +1,5 @@ +namespace Mul_ExpectedOutput{ + float outputs[] = { + 0, 2 + }; +} // namespace Mul_ExpectedOutput \ No newline at end of file diff --git a/tmva/sofie/test/input_models/references/Sub.ref.hxx b/tmva/sofie/test/input_models/references/Sub.ref.hxx new file mode 100644 index 0000000000000..bd2ac99126068 --- /dev/null +++ b/tmva/sofie/test/input_models/references/Sub.ref.hxx @@ -0,0 +1,5 @@ +namespace Sub_ExpectedOutput{ + float outputs[] = { + 1, 1 + }; +} // namespace Sub_ExpectedOutput \ No newline at end of file diff --git a/tmva/sofie_parsers/inc/TMVA/RModelParser_ONNX.hxx b/tmva/sofie_parsers/inc/TMVA/RModelParser_ONNX.hxx index c8acaa412a185..dd3a9fd01b21b 100644 --- a/tmva/sofie_parsers/inc/TMVA/RModelParser_ONNX.hxx +++ b/tmva/sofie_parsers/inc/TMVA/RModelParser_ONNX.hxx @@ -23,6 +23,7 @@ namespace Experimental{ namespace SOFIE{ namespace INTERNAL{ +// enum EBasicBinaryOperator { Add, Sub, Mul, Div }; std::unique_ptr make_ROperator_Transpose(const onnx::NodeProto& nodeproto, const onnx::GraphProto& graphproto, std::unordered_map& tensor_type); std::unique_ptr make_ROperator_Relu(const onnx::NodeProto& nodeproto, const onnx::GraphProto& graphproto, std::unordered_map& tensor_type); @@ -35,7 +36,7 @@ std::unique_ptr make_ROperator_RNN(const onnx::NodeProto& nodeproto, std::unique_ptr make_ROperator_LSTM(const onnx::NodeProto& nodeproto, const onnx::GraphProto& graphproto, std::unordered_map& tensor_type); std::unique_ptr make_ROperator_BatchNormalization(const onnx::NodeProto& nodeproto, const onnx::GraphProto& graphproto, std::unordered_map& tensor_type); std::unique_ptr make_ROperator_Pool(const onnx::NodeProto& nodeproto, const onnx::GraphProto& graphproto, std::unordered_map& tensor_type); -std::unique_ptr make_ROperator_Add(const onnx::NodeProto &nodeproto, const onnx::GraphProto &graphproto, std::unordered_map &tensor_type); +template std::unique_ptr make_ROperator_BasicBinary(const onnx::NodeProto &nodeproto, const onnx::GraphProto &graphproto, std::unordered_map &tensor_type); std::unique_ptr make_ROperator_Reshape(const onnx::NodeProto &nodeproto, const onnx::GraphProto &graphproto, std::unordered_map &tensor_type); std::unique_ptr make_ROperator_Slice(const onnx::NodeProto &nodeproto, const onnx::GraphProto &graphproto, std::unordered_map &tensor_type); std::unique_ptr make_ROperator_GRU(const onnx::NodeProto& nodeproto, const onnx::GraphProto& graphproto, std::unordered_map& tensor_type); @@ -57,7 +58,10 @@ const factoryMethodMap mapOptypeOperator = { {"AveragePool", &make_ROperator_Pool}, {"GlobalAveragePool", &make_ROperator_Pool}, {"MaxPool", &make_ROperator_Pool}, - {"Add", &make_ROperator_Add}, + {"Add", &make_ROperator_BasicBinary}, + {"Sub", &make_ROperator_BasicBinary}, + {"Mul", &make_ROperator_BasicBinary}, + {"Div", &make_ROperator_BasicBinary
}, {"Reshape", &make_ROperator_Reshape}, {"Flatten", &make_ROperator_Reshape}, {"Slice", &make_ROperator_Slice}, diff --git a/tmva/sofie_parsers/src/RModelParser_ONNX.cxx b/tmva/sofie_parsers/src/RModelParser_ONNX.cxx index 92f06c265beaa..91e27ecc64ec6 100644 --- a/tmva/sofie_parsers/src/RModelParser_ONNX.cxx +++ b/tmva/sofie_parsers/src/RModelParser_ONNX.cxx @@ -23,8 +23,9 @@ std::unique_ptr make_ROperator(size_t idx, const onnx::GraphProto& gr return (find->second)(nodeproto, graphproto, tensor_type); } } - -std::unique_ptr make_ROperator_Add(const onnx::NodeProto& nodeproto, const onnx::GraphProto& /*graphproto */, std::unordered_map& tensor_type){ +// enum EBasicBinaryOperator { Add, Sub, Mul, Div }; +template +std::unique_ptr make_ROperator_BasicBinary(const onnx::NodeProto& nodeproto, const onnx::GraphProto& graphproto, std::unordered_map& tensor_type){ ETensorType input_type = ETensorType::UNDEFINED; @@ -37,7 +38,16 @@ std::unique_ptr make_ROperator_Add(const onnx::NodeProto& nodeproto, else assert(it->second == input_type); } else { - throw std::runtime_error("TMVA::SOFIE ONNX Parser Add op has input tensor" + input_name + " but its type is not yet registered"); + // check if input tensor is an initialized tensor + bool isInitializer = false; + for (int j=0; j < graphproto.initializer_size(); j++){ + if (input_name == graphproto.initializer(j).name()) { + isInitializer = true; + break; + } + } + if (!isInitializer) + throw std::runtime_error("TMVA::SOFIE ONNX Parser Binary op has input tensor " + input_name + " but its type is not yet registered"); } } @@ -45,10 +55,10 @@ std::unique_ptr make_ROperator_Add(const onnx::NodeProto& nodeproto, switch(input_type){ case ETensorType::FLOAT: - op.reset(new ROperator_Add(nodeproto.input(0), nodeproto.input(1), nodeproto.output(0))); + op.reset(new ROperator_BasicBinary(nodeproto.input(0), nodeproto.input(1), nodeproto.output(0))); break; default: - throw std::runtime_error("TMVA::SOFIE - Unsupported - Operator Add does not yet support input type " + std::to_string(static_cast(input_type))); + throw std::runtime_error("TMVA::SOFIE - Unsupported - Binary Operator does not yet support input type " + std::to_string(static_cast(input_type))); } ETensorType output_type = (op->TypeInference({input_type}))[0]; @@ -59,6 +69,7 @@ std::unique_ptr make_ROperator_Add(const onnx::NodeProto& nodeproto, return op; } + std::unique_ptr make_ROperator_Transpose(const onnx::NodeProto& nodeproto, const onnx::GraphProto& /*graphproto*/, std::unordered_map& tensor_type){ ETensorType input_type; @@ -149,9 +160,9 @@ std::unique_ptr make_ROperator_LeakyRelu(const onnx::NodeProto& nodep for (int_t i = 0; i < nodeproto.attribute_size(); i++) { std::string attribute_name = nodeproto.attribute(i).name(); - if (attribute_name == "alpha") + if (attribute_name == "alpha") attr_alpha = nodeproto.attribute(i).f(); - } + } switch(input_type){ case ETensorType::FLOAT: op.reset(new ROperator_LeakyRelu(attr_alpha,nodeproto.input(0), nodeproto.output(0))); @@ -474,7 +485,7 @@ std::unique_ptr make_ROperator_Pool(const onnx::NodeProto& nodeproto, RAttributes_Pool attr; // std::string attr_auto_pad = "NOTSET"; // int attr_ceil_mode = 0; - // int attr_count_include_pad = 0; + // int attr_count_include_pad = 0; // int attr_storage_order = 0; // not for AveragePool // std::vector attr_dilations; // not for AveragePool // std::vector attr_kernel_shape; @@ -530,22 +541,22 @@ std::unique_ptr make_ROperator_Reshape(const onnx::NodeProto &nodepro // make Reshape operator ETensorType input_type = ETensorType::UNDEFINED; - + ReshapeOpMode opMode = Reshape; - if (nodeproto.op_type() == "Flatten") + if (nodeproto.op_type() == "Flatten") opMode = Flatten; - else if (nodeproto.op_type() == "Squeeze") + else if (nodeproto.op_type() == "Squeeze") opMode = Squeeze; else if (nodeproto.op_type() == "Unsqueeze") opMode = Unsqueeze; - + //bool hasShapeInput = (opMode == Reshape) ? true : false; - // reshape has as extra input shape tensor (int64) but + // reshape has as extra input shape tensor (int64) but // it is not present for Flatten, Squeeze and Unsquueze auto input_name = nodeproto.input(0); - // for squeeze is optional ? + // for squeeze is optional ? auto shape_name = (opMode == Reshape || opMode == Unsqueeze) ? nodeproto.input(1) : ""; auto it = tensor_type.find(input_name); if (it != tensor_type.end()) { @@ -559,7 +570,7 @@ std::unique_ptr make_ROperator_Reshape(const onnx::NodeProto &nodepro // Flatten is having one attribute: axis (int) (default=1) // old version of reshape and squeeze have axes as attributes std::unique_ptr op; - int attr_value = (opMode == Reshape) ? 0 : 1; + int attr_value = (opMode == Reshape) ? 0 : 1; if (opMode == Reshape && nodeproto.attribute_size() > 0 ) attr_value = nodeproto.attribute(0).i(); From 9489b335891f93b993a04c95d73e1e257654cb3e Mon Sep 17 00:00:00 2001 From: Neel-Shah-29 Date: Thu, 30 Jun 2022 21:33:29 +0530 Subject: [PATCH 103/104] Required changes related to comments are done. --- tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx | 8 +++----- tmva/sofie/inc/TMVA/SOFIE_common.hxx | 2 +- tmva/sofie_parsers/inc/TMVA/RModelParser_ONNX.hxx | 1 - tmva/sofie_parsers/src/RModelParser_ONNX.cxx | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx b/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx index 4a26526b113e7..7416d69432770 100644 --- a/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx +++ b/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx @@ -81,7 +81,8 @@ public: } auto shapeX1 = model.GetTensorShape(fNX1); auto shapeX2 = model.GetTensorShape(fNX2); - // assume same shape X1 and X2 + // If the shape of 2 tensors are not same we perform multi-directional Broadcasting. + // We only support tensors with same length and the resultant output length should also be same. if (shapeX1 != shapeX2) { fShape = UTILITY::Multidirectional_broadcast(shapeX1,shapeX2); size_t length1 = ConvertShapeToLength(shapeX1); @@ -91,6 +92,7 @@ public: throw std::runtime_error(std::string("TMVA SOFIE Binary Op does not support input tensors with different lengths. The output tensor should also have the same length as the input tensors.")); } } + // If both the tensors have same shape then assign the same shape to resultant output. else if(shapeX1 == shapeX2){ fShape = shapeX1; } @@ -105,10 +107,6 @@ public: throw std::runtime_error("TMVA SOFIE Binary Op called to Generate without being initialized first"); } std::stringstream out; - // int length = 1; - // for(auto& i: fShape){ - // length *= i; - // } size_t length = ConvertShapeToLength(fShape); out << "\n//------ " + std::string(BinaryOperatorTrait::Name())+"\n"; out << SP << "for (size_t id = 0; id < " << length << " ; id++){\n"; diff --git a/tmva/sofie/inc/TMVA/SOFIE_common.hxx b/tmva/sofie/inc/TMVA/SOFIE_common.hxx index 6f72b27104c5a..0b65b416dfe5c 100644 --- a/tmva/sofie/inc/TMVA/SOFIE_common.hxx +++ b/tmva/sofie/inc/TMVA/SOFIE_common.hxx @@ -105,7 +105,7 @@ ETensorType GetTemplatedType(T /*obj*/ ){ namespace UTILITY{ template T* Unidirectional_broadcast(const T* original_data, const std::vector original_shape, const std::vector target_shape); -std::vector Multidirectional_broadcast(const std::vector input1_shape, const std::vector input2_shape); +std::vector Multidirectional_broadcast(std::vector input1_shape, std::vector input2_shape); std::string Clean_name(std::string input_tensor_name); diff --git a/tmva/sofie_parsers/inc/TMVA/RModelParser_ONNX.hxx b/tmva/sofie_parsers/inc/TMVA/RModelParser_ONNX.hxx index dd3a9fd01b21b..05d97754c1b9e 100644 --- a/tmva/sofie_parsers/inc/TMVA/RModelParser_ONNX.hxx +++ b/tmva/sofie_parsers/inc/TMVA/RModelParser_ONNX.hxx @@ -23,7 +23,6 @@ namespace Experimental{ namespace SOFIE{ namespace INTERNAL{ -// enum EBasicBinaryOperator { Add, Sub, Mul, Div }; std::unique_ptr make_ROperator_Transpose(const onnx::NodeProto& nodeproto, const onnx::GraphProto& graphproto, std::unordered_map& tensor_type); std::unique_ptr make_ROperator_Relu(const onnx::NodeProto& nodeproto, const onnx::GraphProto& graphproto, std::unordered_map& tensor_type); diff --git a/tmva/sofie_parsers/src/RModelParser_ONNX.cxx b/tmva/sofie_parsers/src/RModelParser_ONNX.cxx index 91e27ecc64ec6..29398d5d78e77 100644 --- a/tmva/sofie_parsers/src/RModelParser_ONNX.cxx +++ b/tmva/sofie_parsers/src/RModelParser_ONNX.cxx @@ -23,7 +23,7 @@ std::unique_ptr make_ROperator(size_t idx, const onnx::GraphProto& gr return (find->second)(nodeproto, graphproto, tensor_type); } } -// enum EBasicBinaryOperator { Add, Sub, Mul, Div }; + template std::unique_ptr make_ROperator_BasicBinary(const onnx::NodeProto& nodeproto, const onnx::GraphProto& graphproto, std::unordered_map& tensor_type){ From 6df2e5eca6d2255712b7780a734ac1954037e798 Mon Sep 17 00:00:00 2001 From: Neel-Shah-29 Date: Thu, 30 Jun 2022 21:39:51 +0530 Subject: [PATCH 104/104] Required changes made for the comments --- tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx b/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx index 7416d69432770..a2772d4eb4f06 100644 --- a/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx +++ b/tmva/sofie/inc/TMVA/ROperator_BasicBinary.hxx @@ -51,8 +51,6 @@ private: std::string fNY; std::vector fShape; - // template - // BinaryOperatorTrait *s; public: ROperator_BasicBinary(){}