Warning in <TROOT::Append>: Replacing existing TH1: XY plane (Potential memory leak)

Hi ROOT community,

I see people have posted about this warning but with a different reason between ‘TH1:’ and ‘(Potential memory leak)’. I’m new enough to ROOT and c++ that I don’t yet have the knowledge to extrapolate their specific solutions to my code. Any help would be great.

My code is below:

////////////////////////////////////Script that defines methods as a .cc file/////////////////////////////////////////////////////////////////
#include "gaps_detector_Evan_2DOrganized.h"
#include <iostream>

Gaps_Detector::Gaps_Detector(int nEl, Float_t vb, Float_t ncharge, int readout)

    //KDetector Gaps_Detector;

    numEl = nEl;
    v_B = vb;
    neff = ncharge;

    SStep= 1;
    nx = 2000;
    ny = 50;
    nz = 1;

    dimX = 97*pow(10,3); //NS change to 4inch diameter -> 97 mm for active area
    dimY = 2.5*pow (10,3); //2.4 mm thick doped silicon
    dimD = 100; // 100um thick dead layer

    //deep and shallow groove
    depthD = 500; //depth of deep groove 500um
    widthD = 1*pow(10,3); //width of deep groove 1mm

    depthS = 350; //depth of shallow groove 350um
    widthS = 1000; //width of shallow groove 750um

    //guard ring and edge of detector
    widthGR = 2.5*pow(10,3); //guard ring width 1mm
    widthE = 1*pow(10,3); //edge width 1mm

    widthGroove = 1000; //750um wide groove between electrodes
    depthGroove = 300; //350um deep groove between electrodes
    widthEl = (dimX - (2*(widthD + widthS) + 2*(widthGR + widthE) + ((numEl-1)*widthGroove)))/numEl; //width of electrodes
    cout << "Electrode width = "<< widthEl << " um" << endl;
    cout << "Groove Width = "<< widthGroove << " um" <<  endl;
    depthEl = .15; //150 nm thick electrode layer ?? you mean 400nm?

    //bias voltage applied to detector
    //init geometry

    //if (EG!=NULL) delete EG;

    EG= new TH3I("EG","geometry",nx,0,dimX,ny,0,dimY,nz,0,1); // Electrode Geometry
    //TH3I *EG= new TH3I("EG","Geometry",nx,0,dimX,ny,0,dimY,nz,0,1); // Electrode Geometry
    EG->GetXaxis()->SetTitle("x [#mum]");
    EG->GetYaxis()->SetTitle("y [#mum]");
    EG->GetZaxis()->SetTitle("z [#mum]");

    //init material
    //if(DM!=NULL) delete DM;
    DM=new TH3I("DM","material",nx,0,dimX,ny,0,dimY,nz,0,1); // Detector material
    //TH3I *DM=new TH3I("DM","Material",nx,0,dimX,ny,0,dimY,nz,0,1); // Detector material
    DM->GetXaxis()->SetTitle("x [#mum]");
    DM->GetYaxis()->SetTitle("y [#mum]");
    DM->GetZaxis()->SetTitle("z [#mum]");

    //init space charge histo
    NeffH=new TH3F("neff","Charge",nx,0,dimX,ny,0,dimY,nz,0,1);
    //TH3F *NeffH=new TH3F("Neff","Charge",nx,0,dimX,ny,0,dimY,nz,0,1);
    NeffH->GetXaxis()->SetTitle("x [#mum]");
    NeffH->GetYaxis()->SetTitle("y [#mum]");
    NeffH->GetZaxis()->SetTitle("z [#mum]");

    //  SetUpMaterial
      // Why would we need to do this every loop???
    for(int j=0;j<=dimY;j++)
      for(int i=0;i<=dimX;i++)
	  DM->SetBinContent(i,j,1,0); // Initializes detector material (xbin i, ybin j, zbin 1, bin content 0)
	  NeffH->SetBinContent(i,j,1,neff); //effective doping concentration histogram, initizalize to neff

    //  Add a dead layer
      /*for(int j=0;j<=dimD;j++)
          for(int i=0;i<=dimX;i++)

    // Collection electrode - set the collection electrode to 1 at the base of the detector for Ramos Theorem
    int Mat = 1; // NS change to 1000 (Al), used to be 1 (poly Silicon?)
    int Wpval=2; //variable for weighting potential, 2 sets bias on plate
    Float_t BackPos[3]={dimX/2, depthEl/2, 0.5};
    Float_t BackSiz[3]={dimX/2, depthEl/2, 0.5};

    //print statement
    cout << "Gaps Detector Initialized"<< endl;
    cout << "number of electrodes: "<< nEl << ", Voltage: "<< vb << "V, Space Charge: " << ncharge<<"E12"<< endl;

    //setting electrodes
    cout << "Readout Electrode is: " << readout <<endl;

void Gaps_Detector::set_Electrodes(int whichReadEl)
          int MatE = 1; //electrode material
          int WpvalE = 1; //ground
          Float_t StripPosAll[8] = {11300,24850,34800,44000,53000,62200,72150,85700};
          Float_t StripSizeAll[8] =  {15600,9500,8400,8000,8000,8400,9500,15600};
          //set guard ring (grounded electrode)
          Float_t GuardRingSiz[3] = {widthGR/2, depthEl/2, 0.5};
          Float_t GuardRing1Pos[3] = {95750, (dimY-depthEl/2), 0.5};
          Float_t GuardRing2Pos[3] ={1250,(dimY-depthEl/2), 0.5};
          ElRectangle(GuardRing1Pos, GuardRingSiz, WpvalE, MatE);
          ElRectangle(GuardRing2Pos, GuardRingSiz, WpvalE, MatE);
          //Set strip electrodes
          Float_t StripPos[3] = {StripPosAll[0], (dimY - depthEl/2), 0.5};
          Float_t StripSiz[3] = {(widthEl/2), depthEl/2, 0.5};
          for( int El =0; El<numEl; El++) //loop through strip electrodes
    	    WpvalE=16385; //16385 designates the read out node
    	    StripPos[0] = StripPosAll[El];
            StripSiz[0] = StripSizeAll[El]/2;
            cout << "Electrode "<< El << " at position "<< StripPos[0] <<  endl;
    	    WpvalE=1; //1 grounds all other electrodes
    	    StripPos[0] = StripPosAll[El];
            StripSiz[0] = StripSizeAll[El]/2;
            cout << "Electrode "<< El << " at position "<< StripPos[0] <<  endl;
          cout <<"electrodes set with read out electrode: " << whichReadEl << endl;

void Gaps_Detector::ElCylinder(Float_t *Pos,Float_t R, Float_t L,Int_t O, Int_t Wei, Int_t Mat)
        // Cylindrical electrode
        // Float_t *Pos;  - postion of the cone center
        Float_t Dist,D,x,y,z,Bu,Bd;
        Int_t i,j,k,q;


                        case 3:   D=TMath::Sqrt(TMath::Power(x-Pos[0],2)+TMath::Power(y-Pos[1],2))-R; break;
                        case 2:   D=TMath::Sqrt(TMath::Power(x-Pos[0],2)+TMath::Power(z-Pos[2],2))-R; break;
                        case 1:   D=TMath::Sqrt(TMath::Power(y-Pos[1],2)+TMath::Power(z-Pos[2],2))-R; break;

                            case 3:   Dist=EG->GetZaxis()->GetBinCenter(k);
                                Bu=Pos[2]+L; Bd=Pos[2]-L; break;
                            case 2:   Dist=EG->GetYaxis()->GetBinCenter(j);
                                Bu=Pos[1]+L; Bd=Pos[1]-L; break;
                            case 1:   Dist=EG->GetXaxis()->GetBinCenter(i);
                                Bu=Pos[0]+L; Bd=Pos[0]-L; break;

                        if(Dist<=Bu && Dist>=Bd)
                            if(EG!=NULL) EG->SetBinContent(i,j,k,Wei);
                            if(DM!=NULL) DM->SetBinContent(i,j,k,Mat);

void Gaps_Detector::changeReadout(int newReadOut){
        readout = newReadOut;

void Gaps_Detector::set_Round_Grooves()
          //Use a cylinder with radius R set to desired groove depth. The if the desired depth is less than 1mm, add a square to fill in empty space between electrodes
            //set deep groove
            Float_t GroovePosAll[9] = {3000,19600,30100,39500,48500,57500,66900,77400,94000};
            int WpvalG = 0; //not an electrode
            int MatG = 20; //air
            int R = 350; //375um radius for shallow grooves and grooves btwn electrodes
            int DR = 500; //500um radius for deep grooves
            int L = 1; //0.5um length
            int O = 3; //orientation
            Float_t DGrooveSiz[3] = {widthD/2, 100, 0.5};
            Float_t DGroove1Pos[3] = {(dimX - (widthE + widthD/2)), (dimY) , 0.5};
            Float_t DGroove2Pos[3] = {(widthE + widthD/2), (dimY) , 0.5};
            ElCylinder(DGroove2Pos, DR, L, O, WpvalG, MatG);
            ElCylinder(DGroove1Pos, DR, L, O, WpvalG, MatG);
            //ElRectangle(DGroove2Pos, DGrooveSiz, WpvalG, MatG);
            //ElRectangle(DGroove1Pos, DGrooveSiz, WpvalG, MatG);
            //set shallow groove
            Float_t SGroove1Pos[3] = {(dimX - (widthE + widthD + widthGR + widthS/2)), (dimY + 25), 0.5};
            Float_t SGroove2Pos[3] = {(widthE + widthD + widthGR + widthS/2), (dimY + 25), 0.5};
            ElCylinder(SGroove2Pos, R, L, O, WpvalG, MatG);
            ElCylinder(SGroove1Pos, R, L, O, WpvalG, MatG);
            //ElRectangle(SGroove2Pos, DGrooveSiz, WpvalG, MatG);
            //ElRectangle(SGroove1Pos, DGrooveSiz, WpvalG, MatG);

            //set grooves between strips
            Float_t GrooveSiz[3] = {widthGroove/2, depthGroove/2, 0.5};
            Float_t GroovePos[3] = {(widthE+widthD+widthS+widthGR+(widthGroove/2)), (dimY + 25), 0.5};
            int numGroove = numEl+1;
            for (int i = 0; i<numGroove; i++)//This loop, separation between i = 0 and i = 1, and i= 1 and i =2
    	   GroovePos[0] = GroovePosAll[i];
            cout << "Groove Position "<< i << " = "<< GroovePos[0] <<  endl;
                ElCylinder(GroovePos, R, L, O, WpvalG, MatG);
                //ElRectangle(GroovePos, DGrooveSiz, WpvalG, MatG);
            cout << "round grooves set"<< endl;

    /// Will we ever use this method? It is out of date with current Shimadzu detector geometry - NS
void Gaps_Detector::switch_readoutEl(int new_readout)

    Float_t StripPos[3] = {(widthE+widthGR+widthD+widthS + (widthEl/2)), (dimY - depthEl/2), 0.5};
    Float_t StripSiz[3] = {(widthEl/2), depthEl/2, 0.5};

    for( int El =0; El<numEl; El++)
	if(El == new_readout)
	    int Wpval = 16385;
	    StripPos[0] = (widthE + widthGR + widthD + widthS)
	      + (El*widthGroove)
	      + (El*widthEl)
	      + (widthEl/2);

	    ElRectangle(StripPos, StripSiz, Wpval, Mat);
	    int Wpval = 1;
	    StripPos[0] = (widthE+ widthGR + widthD + widthS)
	      + (El*widthGroove)
	      + (El*widthEl)
	      + (widthEl/2);

	    ElRectangle(StripPos, StripSiz, Wpval, Mat);

	//resetting boundary conditions and field

////////////////////////////////////Header file/////////////////////////////////////////////////////////////////

#include <iostream>

class Gaps_Detector: public KDetector


  int numEl;  //number of electrodes
  Float_t v_B;    //voltage applied to bottom place
  Float_t neff;   //space charge density in units 10^12 [cm^-3]

  int readout; //read out electrode

  Float_t dimX, dimY, dimD;

  Float_t depthS, widthS; //shallow groove depth and width
  Float_t depthD, widthD; //deep groove depth and width

  Float_t widthGR, widthE; //width of guard ring and edge of detector

  Float_t widthGroove, depthGroove; //width and depth of grooves
  Float_t widthEl, depthEl; //width and depth of electrodes

  int nx, ny, nz, SStep; // grid size
  string detector_name;

  Gaps_Detector(int nEl, Float_t vb, Float_t ncharge, int readout);

  void set_Electrodes(int whichReadEl);

  void ElCylinder(Float_t *Pos,Float_t R, Float_t L,Int_t O, Int_t Wei, Int_t Mat);
  void changeReadout(int newReadOut);

  void set_Round_Grooves();
  void switch_readoutEl(int new_readout);


sorry for the late reply. The error typically means that you are creating multiple objects with the same name. You can check where exactly that happens in your code by stepping through it with gdb or by simply adding printouts here and there.

I could investigate your specific case a bit more if you provide a standalone version that I can run (e.g. one that does not depend on KDetector).


Hey Enrico,

Thank you for the reply. I’m adding print statements throughout the script to see if I can spot the double agent. I’m curious, though, where it could be. As you can see in the script i uploaded for this post, each of my 3D histograms, ‘EG’, ‘DM’, and ‘NeffH’ have different names. So must the problem lie somewhere in the KDetector class definition?

Lastly, by ‘gdb’, do you mean geodatabase?


Lastly, by ‘gdb’, do you mean geodatabase?

No, I mean the GNU debugger! http://www.gdbtutorial.com
With a debugger you can stop your program and inspect what it is doing, and resume execution step by step. It’s very useful for…debugging!

Anyways, feel free to ping us here if you manage to put together a minimal, self-contained reproducer.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.