Creating Multiple Copies of a Composite Shape

Hello all,
I am a newbie to ROOT. I am currently working on a code I discovered online. My aim is to construct a Positron Emitting Tomography Ring. By employing the code below, I managed to create two opposite photodetectors with an angle 180 degrees. However, I want to create an entire ring composed of many photodetectors such as in the following image.

Considering that creating opposite detectors many times is not utile, how can I create such a ring in one step? Any help would be greatly appreciated. Currently I was able to create the following opposite photodetectors:

_ROOT Version:
From tags/v6-24-06@v6-24-06 |
| With Apple clang version 13.0.0 (clang-1300.0.29.3)

The code:

#include “TGeoManager.h”

#include iostream>

#include cmath>

using namespace std;

void photodetector ()

{

// gStyle->SetCanvasPreferGL(true);

gSystem->Load(“libGeom”);

TGeoManager *geom = new TGeoManager(“world”, “Simple geometry”);

//— define some materials

TGeoMaterial *matVacuum = new TGeoMaterial(“Vacuum”, 0,0,0);

TGeoMaterial *matAl = new TGeoMaterial(“Al”, 26.98,13,2.7);

TGeoMaterial *matSi = new TGeoMaterial(“Si”, 28.0855,14,2.3290);

//— define some media

TGeoMedium *Vacuum = new TGeoMedium(“Vacuum”, 1, matVacuum);

TGeoMedium *Al = new TGeoMedium(“Al”,2, matAl);

TGeoMedium *Si = new TGeoMedium(“Si”,4, matSi);

//— make mixture lead glass

TGeoElementTable *table = gGeoManager->GetElementTable();

TGeoElement *el1 = table->GetElement(8);

TGeoElement *el2 = table->GetElement(48);

TGeoElement *el3 = table->GetElement(74);

TGeoMixture *cadmiumt = new TGeoMixture(“cadmiumt”,5,7.9);

cadmiumt->AddElement(el1,0.177);

cadmiumt->AddElement(el2,0.313);

cadmiumt->AddElement(el3,0.510);

printf("___________________________________________________________\n"); printf(“Cadmium tungstate:\n”);

cadmiumt->Print();

TGeoMedium *mcadmiumt = new TGeoMedium(“cadmiumt”,5, cadmiumt);

//define the top container volume

TGeoVolume *top = geom->MakeBox(“TOP”,Vacuum, 110, 110, 110);

top->SetLineColor(kMagenta);

geom->SetTopVolume(top);

top->SetVisibility(false);

// make detector

TGeoVolume *D = geom->MakeBox(“D”, Vacuum, 100, 100, 100);

D->SetVisibility(false);

// make boxes

TGeoVolume *box1 = geom->MakeBox(“box1”,Al,4.5,0.6,0.6);

TGeoVolume *box2 = geom->MakeBox(“box2”, Vacuum, 4.5,0.45,0.45);

TGeoVolume *box3 = geom->MakeBox(“box3”, mcadmiumt, 4.5,0.45,0.45);

// SiPm Silicon

TGeoVolume *box4 = geom->MakeBox(“box4”, Si, 0.2,0.45,0.45);

TGeoTranslation *t1 = new TGeoTranslation(“t1”, 4.7,0,0);

t1->RegisterYourself();

//composition

TGeoCompositeShape *cs = new TGeoCompositeShape(“cs”,"((box1-box2)+box3)+box4:t1");

TGeoVolume *comp = new TGeoVolume(“COMP”, cs);

comp->SetLineColor(5);

D->AddNode(comp, 1);

// create matrix

D->AddNode(comp,1,new TGeoTranslation(0.,1.2,0.));

D->AddNode(comp,2,new TGeoTranslation(0.,2.4,0.));

D->AddNode(comp,3,new TGeoTranslation(0.,3.6,0.));

D->AddNode(comp,4,new TGeoTranslation(0.,4.8,0.));

D->AddNode(comp,5,new TGeoTranslation(0.,6.0,0.));

D->AddNode(comp,5,new TGeoTranslation(0.,7.2,0.));

double z;

for ( int i=1; i<=6; i=1+i )

{

z= (1.2*i);
D->AddNode(comp,i,new TGeoTranslation(0.,0.,z));

D->AddNode(comp,i+3,new TGeoTranslation(0.,1.2,z));

D->AddNode(comp,i+4,new TGeoTranslation(0.,2.4,z));

D->AddNode(comp,i+5,new TGeoTranslation(0.,3.6,z));

D->AddNode(comp,i+6,new TGeoTranslation(0.,4.8,z));

D->AddNode(comp,i+7,new TGeoTranslation(0.,6.0,z));

D->AddNode(comp,i+8,new TGeoTranslation(0.,7.2,z));

} //duplicate matrix

top->AddNode(D,1,new TGeoTranslation(41.5,-3.6,-3.6));

TGeoRotation *r1 = new TGeoRotation(“r1”,180,0,0 );

TGeoCombiTrans *c1 = new TGeoCombiTrans(-41.5,3.6,-3.6,r1);

top->AddNode(D,2,c1);

// close geometry
geom->CloseGeometry();

gGeoManager->GetMasterVolume()->Draw();

comp->SetLineColor(kBlue);

}

I think @agheata can help you.

1 Like

thank you @couet

Hi, you can use a tube shape to define the ring containing detector elements. Volumes can be divided along some coordinate, in particular tubes can be divided in phi, creating replicated sectors. Then placing your detector in the common sector volume places it automatically symmetrically all over the ring. Just look at your modified geometry that I attached. You should make sure that the detector is placed in the common sector without exceeding its boundaries (the common sector is centered in phi=0)
photodetector.C (3.6 KB)

Hello, thank you so very much for your response, I have been studying it for several hours and for the detector to be placed in the common sector I have made a change such as: sector->AddNode(D, 1, new TGeoTranslation(93,-3.6,-3.6)); (It was 41.5 before). I hope this is the correct change. Right now, I am trying to make a complete ring. In order to realize this I thought that increasing the sector number from 20 to 100 would be sufficient. It seems to be okay when viewed with OpenGL, however in the first screen that appears, It can be observed that the detectors cross each other.

If it is not too much work, can I ask how to manage to create a continuous tomography ring design such as in the next figure, without the presence of such intersections of detectors? An exemplary design of what I am trying to make is such as in this image: Thanks in advance. @agheata

The code I used is:

#include <TGeoManager.h>

#include< iostream>

#include< cmath>

using namespace std;

void photodetector ()

{

// gStyle->SetCanvasPreferGL(true);

gSystem->Load(“libGeom”);

TGeoManager *geom = new TGeoManager(“world”, “Simple geometry”);

//— define some materials

TGeoMaterial *matVacuum = new TGeoMaterial(“Vacuum”, 0,0,0);

TGeoMaterial *matAl = new TGeoMaterial(“Al”, 26.98,13,2.7);

TGeoMaterial *matSi = new TGeoMaterial(“Si”, 28.0855,14,2.3290);

//— define some media

TGeoMedium *Vacuum = new TGeoMedium(“Vacuum”, 1, matVacuum);

TGeoMedium *Al = new TGeoMedium(“Al”,2, matAl);

TGeoMedium *Si = new TGeoMedium(“Si”,4, matSi);

//— make mixture lead glass

TGeoElementTable *table = gGeoManager->GetElementTable();

TGeoElement *el1 = table->GetElement(8);

TGeoElement *el2 = table->GetElement(48);

TGeoElement *el3 = table->GetElement(74);

TGeoMixture *cadmiumt = new TGeoMixture(“cadmiumt”,5,7.9);

cadmiumt->AddElement(el1,0.177);

cadmiumt->AddElement(el2,0.313);

cadmiumt->AddElement(el3,0.510);

printf("___________________________________________________________\n"); printf(“Cadmium tungstate:\n”);

cadmiumt->Print();

TGeoMedium *mcadmiumt = new TGeoMedium(“cadmiumt”,5, cadmiumt);

//define the top container volume

TGeoVolume *top = geom->MakeBox(“TOP”,Vacuum, 110, 110, 110);

top->SetLineColor(kMagenta);

geom->SetTopVolume(top);

top->SetVisibility(false);

// make detector

TGeoVolume *D = geom->MakeBox(“D”, Vacuum, 100, 100, 100);

D->SetVisibility(false);

// make boxes

TGeoVolume *box1 = geom->MakeBox(“box1”,Al,4.5,0.6,0.6);

TGeoVolume *box2 = geom->MakeBox(“box2”, Vacuum, 4.5,0.45,0.45);

TGeoVolume *box3 = geom->MakeBox(“box3”, mcadmiumt, 4.5,0.45,0.45);

// SiPm Silicon

TGeoVolume *box4 = geom->MakeBox(“box4”, Si, 0.2,0.45,0.45);

TGeoTranslation *t1 = new TGeoTranslation(“t1”, 4.7,0,0);

t1->RegisterYourself();

//composition

TGeoCompositeShape *cs = new TGeoCompositeShape(“cs”,"((box1-box2)+box3)+box4:t1");

TGeoVolume *comp = new TGeoVolume(“COMP”, cs);

comp->SetLineColor(5);

D->AddNode(comp, 1);

// create matrix

D->AddNode(comp,1,new TGeoTranslation(0.,1.2,0.));

D->AddNode(comp,2,new TGeoTranslation(0.,2.4,0.));

D->AddNode(comp,3,new TGeoTranslation(0.,3.6,0.));

D->AddNode(comp,4,new TGeoTranslation(0.,4.8,0.));

D->AddNode(comp,5,new TGeoTranslation(0.,6.0,0.));

D->AddNode(comp,6,new TGeoTranslation(0.,7.2,0.));

double z;

for ( int i=1; i<=6; i=1+i )

{

z= (1.2*i);

D->AddNode(comp,i,new TGeoTranslation(0.,0.,z));

D->AddNode(comp,i+3,new TGeoTranslation(0.,1.2,z));

D->AddNode(comp,i+4,new TGeoTranslation(0.,2.4,z));

D->AddNode(comp,i+5,new TGeoTranslation(0.,3.6,z));

D->AddNode(comp,i+6,new TGeoTranslation(0.,4.8,z));

D->AddNode(comp,i+7,new TGeoTranslation(0.,6.0,z));

D->AddNode(comp,i+8,new TGeoTranslation(0.,7.2,z));

} //duplicate matrix

// make container ring

auto ring = geom->MakeTube(“ring”, Vacuum, 35, 49, 8.4);

// divide ring in sectors that will hold each detector

auto sector = ring->Divide(“Sector”, 2 , 100 , 0, 0 );

sector->AddNode(D, 1, new TGeoTranslation(93,-3.6,-3.6));

top->AddNode(ring, 1);

// close geometry

geom->CloseGeometry();

gGeoManager->GetMasterVolume()->Draw();

comp->SetLineColor(kBlue);

}

The constraints you seem to have is the number of detector modules (24 and not 100) and the fact that they are touching on the inner radius part of the detector ring. From these you can easily extract the geometry parameters of the ring (and detector modules) and the way to divide it. From the design you have, just draw the inner and outer circles of the ring so that they are just touching the modules without crossing them, then compute their radius. Then just measure the distance from the setup center to the center of the rightmost detector module (at phi= 0). This distance is the value that you need to use for the translation, when you position the detector D inside the sector. Of course the composition of the detector D made of smaller modules has to be accurate as in your design. It looks that in your current code the modules extend symmetrically along X, but not along Y and Z, and this my generate overlaps. D should fit a box centered in its origin, so maybe re-check the way you apply the translations for your composite shape to have a symmetric distribution in the YZ plane with respect to the origin. If you get all these parameters right, you should get the same representation as in your attached drawing.

Thank you for your reply. I studied your guidance and thought of calculating the translation in the following manner for simplicity (as I am a newly learning ROOT).

I employed the “circumference of a circle” formula with an unknown radius and equated it to total length of the detectors such as : 2pir=24*7(number of matrices)*1.2(length of each matrix) and I calculated r as 32.0856.
I thought this is the distance from the setup center to the beginning of the detector. Thus, in order to find the center of the detector, I added 4.7 (half size of the detector ) to this distance and rounded the total to 36.8. I obtained the following figure.

Visually it seems correct to me, I don’t spot any intersections of detectors. However, I don’t know how to check if the distribution is symmetric in the YZ plane and cannot tell if it is appropriately symmetric and if this final version a correct design. Can you advise me concerning this ? I sincerely appreciate all your help. @agheata

The Code:

#include <TGeoManager.h>

#include< iostream>

#include

using namespace std;

void photodetector ()

{

// gStyle->SetCanvasPreferGL(true);

gSystem->Load(“libGeom”);

TGeoManager *geom = new TGeoManager(“world”, “Simple geometry”);

//— define some materials

TGeoMaterial *matVacuum = new TGeoMaterial(“Vacuum”, 0,0,0);

TGeoMaterial *matAl = new TGeoMaterial(“Al”, 26.98,13,2.7);

TGeoMaterial *matSi = new TGeoMaterial(“Si”, 28.0855,14,2.3290);

//— define some media

TGeoMedium *Vacuum = new TGeoMedium(“Vacuum”, 1, matVacuum);

TGeoMedium *Al = new TGeoMedium(“Al”,2, matAl);

TGeoMedium *Si = new TGeoMedium(“Si”,4, matSi);

//— make mixture lead glass

TGeoElementTable *table = gGeoManager->GetElementTable();

TGeoElement *el1 = table->GetElement(8);

TGeoElement *el2 = table->GetElement(48);

TGeoElement *el3 = table->GetElement(74);

TGeoMixture *cadmiumt = new TGeoMixture(“cadmiumt”,5,7.9);

cadmiumt->AddElement(el1,0.177);

cadmiumt->AddElement(el2,0.313);

cadmiumt->AddElement(el3,0.510);

printf("___________________________________________________________\n"); printf(“Cadmium tungstate:\n”);

cadmiumt->Print();

TGeoMedium *mcadmiumt = new TGeoMedium(“cadmiumt”,5, cadmiumt);

//define the top container volume

TGeoVolume *top = geom->MakeBox(“TOP”,Vacuum, 110, 110, 110);

top->SetLineColor(kMagenta);

geom->SetTopVolume(top);

top->SetVisibility(false);

// make detector

TGeoVolume *D = geom->MakeBox(“D”, Vacuum, 100, 100, 100);

D->SetVisibility(false);

// make boxes

TGeoVolume *box1 = geom->MakeBox(“box1”,Al,4.5,0.6,0.6);

TGeoVolume *box2 = geom->MakeBox(“box2”, Vacuum, 4.5,0.45,0.45);

TGeoVolume *box3 = geom->MakeBox(“box3”, mcadmiumt, 4.5,0.45,0.45);

// SiPm Silicon

TGeoVolume *box4 = geom->MakeBox(“box4”, Si, 0.2,0.45,0.45);

TGeoTranslation *t1 = new TGeoTranslation(“t1”, 4.7,0,0);

t1->RegisterYourself();

//composition

TGeoCompositeShape *cs = new TGeoCompositeShape(“cs”,"((box1-box2)+box3)+box4:t1");

TGeoVolume *comp = new TGeoVolume(“COMP”, cs);

comp->SetLineColor(5);

D->AddNode(comp, 1);

// create matrix

D->AddNode(comp,1,new TGeoTranslation(0.,1.2,0.));

D->AddNode(comp,2,new TGeoTranslation(0.,2.4,0.));

D->AddNode(comp,3,new TGeoTranslation(0.,3.6,0.));

D->AddNode(comp,4,new TGeoTranslation(0.,4.8,0.));

D->AddNode(comp,5,new TGeoTranslation(0.,6.0,0.));

D->AddNode(comp,6,new TGeoTranslation(0.,7.2,0.));

double z;

for ( int i=1; i<=6; i=1+i )

{

z= (1.2*i);

D->AddNode(comp,i,new TGeoTranslation(0.,0.,z));

D->AddNode(comp,i+3,new TGeoTranslation(0.,1.2,z));

D->AddNode(comp,i+4,new TGeoTranslation(0.,2.4,z));

D->AddNode(comp,i+5,new TGeoTranslation(0.,3.6,z));

D->AddNode(comp,i+6,new TGeoTranslation(0.,4.8,z));

D->AddNode(comp,i+7,new TGeoTranslation(0.,6.0,z));

D->AddNode(comp,i+8,new TGeoTranslation(0.,7.2,z));

} //duplicate matrix

// make container ring

auto ring = geom->MakeTube(“ring”, Vacuum, 35, 49, 8.4);

// divide ring in sectors that will hold each detector

auto sector = ring->Divide(“Sector”, 2 , 24,0, 0);

sector->AddNode(D, 1, new TGeoTranslation(36.8,-3.6,-3.6)); // Make sure the sector actually fits the detector

top->AddNode(ring, 1);

// close geometry

geom->CloseGeometry();

gGeoManager->GetMasterVolume()->Draw();

comp->SetLineColor(kBlue);

}

Hello @agheata, sorry for bothering you so frequently. In my last reply (11h ago) I thought that the construction was okay and terminated. However, now, I wanted to check again but remarked that the detectors are not fully in touch, there are small distances between them as in the image.

I took the translation as 36.8, when I decrease this number to 36.5 the distance decreases but does not entirely vanish, and there is no mathematical evidence that I should take it as 36.5 or lower, I just tested it manually. How can I make it sure that the detectors are fully in touch with no intersection. Can you please help me concerning this problem? Thanks in advance .

The code I used:

#include <TGeoManager.h>

#include< iostream>

#include< cmath>

using namespace std;

void photodetector ()

{

// gStyle->SetCanvasPreferGL(true);

gSystem->Load(“libGeom”);

TGeoManager *geom = new TGeoManager(“world”, “Simple geometry”);

//— define some materials

TGeoMaterial *matVacuum = new TGeoMaterial(“Vacuum”, 0,0,0);

TGeoMaterial *matAl = new TGeoMaterial(“Al”, 26.98,13,2.7);

TGeoMaterial *matSi = new TGeoMaterial(“Si”, 28.0855,14,2.3290);

//— define some media

TGeoMedium *Vacuum = new TGeoMedium(“Vacuum”, 1, matVacuum);

TGeoMedium *Al = new TGeoMedium(“Al”,2, matAl);

TGeoMedium *Si = new TGeoMedium(“Si”,4, matSi);

//— make mixture lead glass

TGeoElementTable *table = gGeoManager->GetElementTable();

TGeoElement *el1 = table->GetElement(8);

TGeoElement *el2 = table->GetElement(48);

TGeoElement *el3 = table->GetElement(74);

TGeoMixture *cadmiumt = new TGeoMixture(“cadmiumt”,5,7.9);

cadmiumt->AddElement(el1,0.177);

cadmiumt->AddElement(el2,0.313);

cadmiumt->AddElement(el3,0.510);

printf("___________________________________________________________\n"); printf(“Cadmium tungstate:\n”);

cadmiumt->Print();

TGeoMedium *mcadmiumt = new TGeoMedium(“cadmiumt”,5, cadmiumt);

//define the top container volume

TGeoVolume *top = geom->MakeBox(“TOP”,Vacuum, 110, 110, 110);

top->SetLineColor(kMagenta);

geom->SetTopVolume(top);

top->SetVisibility(false);

// make detector

TGeoVolume *D = geom->MakeBox(“D”, Vacuum, 100, 100, 100);

D->SetVisibility(false);

// make boxes

TGeoVolume *box1 = geom->MakeBox(“box1”,Al,4.5,0.6,0.6);

TGeoVolume *box2 = geom->MakeBox(“box2”, Vacuum, 4.5,0.45,0.45);

TGeoVolume *box3 = geom->MakeBox(“box3”, mcadmiumt, 4.5,0.45,0.45);

// SiPm Silicon

TGeoVolume *box4 = geom->MakeBox(“box4”, Si, 0.2,0.45,0.45);

TGeoTranslation *t1 = new TGeoTranslation(“t1”, 4.7,0,0);

t1->RegisterYourself();

//composition

TGeoCompositeShape *cs = new TGeoCompositeShape(“cs”,"((box1-box2)+box3)+box4:t1");

TGeoVolume *comp = new TGeoVolume(“COMP”, cs);

comp->SetLineColor(5);

D->AddNode(comp, 1);

// create matrix

D->AddNode(comp,1,new TGeoTranslation(0.,1.2,0.));

D->AddNode(comp,2,new TGeoTranslation(0.,2.4,0.));

D->AddNode(comp,3,new TGeoTranslation(0.,3.6,0.));

D->AddNode(comp,4,new TGeoTranslation(0.,4.8,0.));

D->AddNode(comp,5,new TGeoTranslation(0.,6.0,0.));

D->AddNode(comp,6,new TGeoTranslation(0.,7.2,0.));

double z;

for ( int i=1; i<=6; i=1+i )

{

z= (1.2*i);

D->AddNode(comp,i,new TGeoTranslation(0.,0.,z));

D->AddNode(comp,i+3,new TGeoTranslation(0.,1.2,z));

D->AddNode(comp,i+4,new TGeoTranslation(0.,2.4,z));

D->AddNode(comp,i+5,new TGeoTranslation(0.,3.6,z));

D->AddNode(comp,i+6,new TGeoTranslation(0.,4.8,z));

D->AddNode(comp,i+7,new TGeoTranslation(0.,6.0,z));

D->AddNode(comp,i+8,new TGeoTranslation(0.,7.2,z));

} //duplicate matrix

// make container ring

auto ring = geom->MakeTube(“ring”, Vacuum, 35, 49, 8.4);

// divide ring in sectors that will hold each detector

auto sector = ring->Divide(“Sector”, 2 , 24,0., 0.);

sector->AddNode(D, 1, new TGeoTranslation(36.8,-3.6,-3.6)); // Make sure the sector actually fits the detector

top->AddNode(ring, 1);

// close geometry

geom->CloseGeometry();

gGeoManager->GetMasterVolume()->Draw();

comp->SetLineColor(kBlue);

}

additionally, I get the error “Warning in TGeoManager::CheckGeometry: Volume “COMP” has no medium: assigned dummy medium and material” Is there any way I can fix this? Thank you very much @agheata

1 Like

Hi,
To position correctly the scintillator crystals in your detector D, consider the following:

  • D is a container volume, whatever you put inside it has to fit the box, but also the different placements of D itself should not overlap each other.
  • Try to make D if possible fitting exactly the content. Now you make it as a box of half-size 100 on each axis, which is far too large so it will not satisfy the condition above. To visualize only the container D and not the content, simply use the code below after you construct the geometry. Your target is to see the picture with touching boxes on a ring, but you will get one with big boxes overlapping each other.
gGeoManager->GetVolume("D")->SetVisibility(true);
gGeoManager->SetVisLevel(3);
gGeoManager->GetTopVolume()->Draw();
  • To fix this and see what gets wrong, first make the size of D box smaller (5 instead of 100), re-run and call:
gGeoManager->GetVolume("D")->SetVisibility(true);
gGeoManager->SetTopVisible();
gGeoManager->GetVolume("D")->Draw();

Now you will get this kind of picture, showing that you are positioning the crystals non-symmetrical with respect to the D box origin. So in your comp positioning loop, make sure you input positions such that you get a symmetrical picture.

  • When you get the above right, shrink the size of the box of D so that it perfectly fits the content (you can do this using an analytical calculation)
  • At the end, positioning D volume with the translation calculated using your formula (which is correct) should lead you to the correct final result.

Good luck!

Simply create comp volume providing a TGeoMedium pointer to the constructor.

Actually looking deeper this formula is not correct, because 2471.2 is not the length of the arc of the circle corresponding to each matrix array, but the length of the corresponding chord. You need that the inner part of the detector ring to be tangent to the inner part of each module. So the inner ring radius should be: Rmin = (l/2)/tan(2pi/48) where l = 7*1.2. The outer part of the detector ring should pass through the outermost corners of each array of 7. You can calculate this also with simple trigonometry (not done here, taking into account the length of the crystals. Then you position D using a translation Rmin + 0.5 * L where L is the length of each crystal.

Hello @agheata, I am extremely grateful for your help. I have been working on changements for a while. Thus, I am responding a little late. Firsly, I changed the addnode structure. I obtained the following image:

Later, I shrinked D, but obtained the following:

As indicated by the black circle I noticed that the composite shape was not placed symmetrically in the x axis.The shape exceeds boundary of the detector. I thought that the box 4 that I placed with “t1” translation to ((box1-box2)+box3) structure was causing this problem. So I thought of adding a corresponding box5 made of vacuum placed in 180 degrees of the box4 structure. I thought that I could create it as invisible and no effect would be present in the overall image. Thus, I created the following image:

So, I obtained a composite shape fit precisely into D.

Later on, I employed Rmin as 4.2/tan(pi/24) thanks to your guidance, and calculated Rmax as sqrt((35.28)/(1-1*cos(pi/24))) from basic cosine theorem. Thus, I obtained the following sector shape :

I think that it is the right shape I should employ. Thus, in order to place the composite shape containing detector D in each sector I used:
double dx=(Rmin)+(0.5*9.8);

sector->AddNode(D, 1, new TGeoTranslation(dx,0,0));

However when I try to create the entire shape, I still get detectors that are not entirely in touch:

Is there any way to fix this problem?I couldn’t find any accurate solutions. Is it due to the part:
"sector->AddNode(D, 1, new TGeoTranslation(dx,0,0));
I thought that this feature adds a detector in each sector with dx distances and and y=0,z=0

PS: Addnode parts may not be very professional, as I am a new user. I thought that for example :
D->AddNode(comp, 1); command puts “comp” volume right in the center(0,0,0) of D volume thus I thought I should create matrices as indicated in the code section.

Additionally, I am currently not able to set invisible the box 5 made of vacuum , though I used box5->SetVisibility(false); For an accurate design, it should not be perceivable. However I could not manage to realize this.

Can you help concerning these problems, if it is not too much work? Thank you very much.

The code:

#include <iostream>
#include <cmath>
#include <Math/UnaryOperators.h>
using namespace std;
void photodetector ()
{
// gStyle->SetCanvasPreferGL(true);
gSystem->Load("libGeom");
TGeoManager *geom = new TGeoManager("world", "Simple geometry");
//— define some materials
TGeoMaterial *matVacuum = new TGeoMaterial("Vacuum", 0,0,0);
TGeoMaterial *matAl = new TGeoMaterial("Al", 26.98,13,2.7);
TGeoMaterial *matSi = new TGeoMaterial("Si", 28.0855,14,2.3290);
//— define some media
TGeoMedium *Vacuum = new TGeoMedium("Vacuum", 1, matVacuum);
TGeoMedium *Al = new TGeoMedium("Al",2, matAl);
TGeoMedium *Si = new TGeoMedium("Si",4, matSi);
//— make mixture lead glass
TGeoElementTable *table = gGeoManager->GetElementTable();
TGeoElement *el1 = table->GetElement(8);
TGeoElement *el2 = table->GetElement(48);
TGeoElement *el3 = table->GetElement(74);
TGeoMixture *cadmiumt = new TGeoMixture("cadmiumt",5,7.9);
cadmiumt->AddElement(el1,0.177);
cadmiumt->AddElement(el2,0.313);
cadmiumt->AddElement(el3,0.510);
printf("___________________________________________________________\n"); printf("Cadmium tungstate:\n");
cadmiumt->Print();
TGeoMedium *mcadmiumt = new TGeoMedium("cadmiumt",5, cadmiumt);
//define the top container volume
TGeoVolume *top = geom->MakeBox("TOP",Vacuum, 110, 110, 110);
top->SetLineColor(kMagenta);
geom->SetTopVolume(top);
top->SetVisibility(false);
// make detector
TGeoVolume *D = geom->MakeBox("D", Vacuum, 4.9,4.2,4.2);
D->SetVisibility(false);
// make boxes
TGeoVolume *box1 = geom->MakeBox("box1",Al,4.5,0.6,0.6);
TGeoVolume *box2 = geom->MakeBox("box2", Vacuum, 4.5,0.45,0.45);
TGeoVolume *box3 = geom->MakeBox("box3", mcadmiumt, 4.5,0.45,0.45);
// SiPm Silicon
TGeoVolume *box4 = geom->MakeBox("box4", Si, 0.2,0.45,0.45);
TGeoVolume *box5 = geom->MakeBox("box5", Vacuum,0.2,0.45,0.45);

TGeoTranslation *t1 = new TGeoTranslation("t1", 4.7,0,0);
TGeoTranslation *t2 = new TGeoTranslation("t2", -4.7,0,0);
t1->RegisterYourself();
t2->RegisterYourself();
//composition
   box5->SetVisibility(false);
TGeoCompositeShape *cs = new TGeoCompositeShape("cs"," (((box1-box2)+box3)+box4:t1)+box5:t2");

     TGeoVolume *comp = new TGeoVolume("COMP", cs);
     comp->SetLineColor(5);
     D->AddNode(comp, 1);

// create matrix
   D->AddNode(comp,1,new TGeoTranslation(0.,-1.2,0.));
   D->AddNode(comp,2,new TGeoTranslation(0.,-2.4,0.));
   D->AddNode(comp,3,new TGeoTranslation(0.,-3.6,0.));
   D->AddNode(comp,1,new TGeoTranslation(0.,1.2,0.));
   D->AddNode(comp,2,new TGeoTranslation(0.,2.4,0.));
   D->AddNode(comp,3,new TGeoTranslation(0.,3.6,0.));
   
   double z;
   for ( int i=1; i<=3; i=1+i )
   {
   z= (1.2*i);
   D->AddNode(comp,i,new TGeoTranslation(0.,0.,z));
   D->AddNode(comp,i+3,new TGeoTranslation(0.,1.2,z));
   D->AddNode(comp,i+4,new TGeoTranslation(0.,2.4,z));
   D->AddNode(comp,i+5,new TGeoTranslation(0.,3.6,z));
 
   }
   for ( int i=1; i<=3; i=1+i )
   {
   z= (-1.2*i);
   D->AddNode(comp,i,new TGeoTranslation(0.,0.,z));
   D->AddNode(comp,i+3,new TGeoTranslation(0.,-1.2,z));
   D->AddNode(comp,i+4,new TGeoTranslation(0.,-2.4,z));
   D->AddNode(comp,i+5,new TGeoTranslation(0.,-3.6,z));
 
   }
  
   
   for ( int i=1; i<=3; i=1+i )
   {
   z= (1.2*i);

   D->AddNode(comp,i+3,new TGeoTranslation(0.,-1.2,z));
   D->AddNode(comp,i+4,new TGeoTranslation(0.,-2.4,z));
   D->AddNode(comp,i+5,new TGeoTranslation(0.,-3.6,z));
 
   }
 
   for ( int i=1; i<=3; i=1+i )
   {
   z= (-1.2*i);
 
   D->AddNode(comp,i+3,new TGeoTranslation(0.,1.2,z));
   D->AddNode(comp,i+4,new TGeoTranslation(0.,2.4,z));
   D->AddNode(comp,i+5,new TGeoTranslation(0.,3.6,z));
 
   }
   auto pi = TMath::Pi();
double Rmin=4.2/tan(pi/24);
double Rmax= sqrt((35.28)/(1-1*cos(pi/24)));
// make container ring
auto ring = geom->MakeTube("ring", Vacuum,Rmin,Rmax, 8.4);
// divide ring in sectors that will hold each detector
auto sector = ring->Divide("Sector", 2 , 24,0., 0.);

   double dx=(Rmin)+(0.5*9.8);
sector->AddNode(D, 1, new TGeoTranslation(dx,0,0)); // Make sure the sector actually fits the detector
top->AddNode(ring, 1);
// close geometry
geom->CloseGeometry();
gGeoManager->GetMasterVolume()->Draw();
comp->SetLineColor(kBlue);
}

Hi,
I’m afraid I’ll not have the time to travel with you towards the final implementation. I think you started now to get a grasp of the basic principles, it may be a matter of correctness of the formulas. The idea is that if you manage to fill the D box in a way that makes the corners of the outermost content with the ones of the D envelope, fitting correctly the container boxes in the sector division placeholder would automatically make the content touch on the inner part. Since you have some Boolean tip exceeding the crystal, you may need to recompute the parameters for the ring radius and positioning such that you connect together the non-extruding part of your crystal grids. You need to position D only in the division cell at phi=0 (translation in X direction), which will automatically fill all others. The rule of thumb is that you need to be accurate geometrically with the design you have at hand.

Hello @agheata, after some reconsiderations of the “addnode” parts, I am finally able to fully and correctly create the design I intended. The design is completed virtually. However, if I am not occupying you too much, may I ask the following:

As observed, 7x7 matrix detector is composed of boxes. I tried to create each box :

  • Firstly, by creating an Alimunium box
  • Then I subtracted a vacuum box from the center of the first box. The vacuum box is smaller than the first box so that there are some small Alimunium portions left behind.
  • Then, I added box 3 made of cadmium medium, which has identical sizes as the vacuum box.
  • Finally, I added at t1 translation Si boxes which represent actually silicon photomultipliers.

Thus I tried to create a composite shape in this manner. As a result the shape has “mcadmiumt” inside, covered by an aluminum material of thickness 0.15 mm and at “t1” alon x axis there is Si material. Consequently, I am not able to define a precise medium such as Al or Si, etc. for the whole shape. This wasn’t an error before when I created two photodetectors placed with 180 degrees of an angle. However, now, with the transformation into a ring design, I get the error: “Warning in TGeoManager::CheckGeometry: Volume “COMP” has no medium: assigned dummy medium and material” If there is a way I can fix this and if you can advise me about this issue, I would be truly grateful.

Finally, I would like to indicate that I am extremely grateful for your help and guidance through the whole process. Thank you truly for all your help and tolerance.

The code employed is found below:

#include <TGeoManager.h>
#include <iostream>
#include <cmath>
#include <Math/UnaryOperators.h>
using namespace std;
void photodetector ()
{
// gStyle->SetCanvasPreferGL(true);
gSystem->Load("libGeom");
TGeoManager *geom = new TGeoManager("world", "Simple geometry");
//— define some materials
TGeoMaterial *matVacuum = new TGeoMaterial("Vacuum", 0,0,0);
TGeoMaterial *matAl = new TGeoMaterial("Al", 26.98,13,2.7);
TGeoMaterial *matSi = new TGeoMaterial("Si", 28.0855,14,2.3290);
//— define some media
TGeoMedium *Vacuum = new TGeoMedium("Vacuum", 1, matVacuum);
TGeoMedium *Al = new TGeoMedium("Al",2, matAl);
TGeoMedium *Si = new TGeoMedium("Si",4, matSi);
//— make mixture lead glass
TGeoElementTable *table = gGeoManager->GetElementTable();
TGeoElement *el1 = table->GetElement(8);
TGeoElement *el2 = table->GetElement(48);
TGeoElement *el3 = table->GetElement(74);
TGeoMixture *cadmiumt = new TGeoMixture("cadmiumt",5,7.9);
cadmiumt->AddElement(el1,0.177);
cadmiumt->AddElement(el2,0.313);
cadmiumt->AddElement(el3,0.510);
printf("___________________________________________________________\n"); printf("Cadmium tungstate:\n");
cadmiumt->Print();
TGeoMedium *mcadmiumt = new TGeoMedium("cadmiumt",5, cadmiumt);
//define the top container volume
TGeoVolume *top = geom->MakeBox("TOP",Vacuum, 110, 110, 110);
top->SetLineColor(kMagenta);
geom->SetTopVolume(top);
top->SetVisibility(false);
// make detector
TGeoVolume *D = geom->MakeBox("D", Vacuum, 4.7,4.2,4.2);
D->SetVisibility(false);
// make boxes
TGeoVolume *box1 = geom->MakeBox("box1",Al,4.5,0.6,0.6);
TGeoVolume *box2 = geom->MakeBox("box2", Vacuum, 4.5,0.45,0.45);
TGeoVolume *box3 = geom->MakeBox("box3", mcadmiumt, 4.5,0.45,0.45);
// SiPm Silicon
TGeoVolume *box4 = geom->MakeBox("box4", Si, 0.2,0.45,0.45);
TGeoVolume *box5 = geom->MakeBox("box5", Vacuum,0.2,0.45,0.45);

TGeoTranslation *t1 = new TGeoTranslation("t1", 4.7,0,0);

t1->RegisterYourself();

//composition
    box5->SetVisibility(false);
TGeoCompositeShape *cs = new TGeoCompositeShape("cs"," ((box1-box2)+box3)+box4:t1");

      TGeoVolume *comp = new TGeoVolume("COMP", cs);
      comp->SetLineColor(5);
    D->AddNode(comp, 1, new TGeoTranslation(-0.2,0,0));

// create matrix
    D->AddNode(comp,1,new TGeoTranslation(-0.2,-1.2,0.));
    D->AddNode(comp,2,new TGeoTranslation(-0.2,-2.4,0.));
    D->AddNode(comp,3,new TGeoTranslation(-0.2,-3.6,0.));
    D->AddNode(comp,1,new TGeoTranslation(-0.2,1.2,0.));
    D->AddNode(comp,2,new TGeoTranslation(-0.2,2.4,0.));
    D->AddNode(comp,3,new TGeoTranslation(-0.2,3.6,0.));
    
    double z;
    for ( int i=1; i<=3; i=1+i )
    {
    z= (1.2*i);
    D->AddNode(comp,i,new TGeoTranslation(-0.2,0.,z));
    D->AddNode(comp,i+3,new TGeoTranslation(-0.2,1.2,z));
    D->AddNode(comp,i+4,new TGeoTranslation(-0.2,2.4,z));
    D->AddNode(comp,i+5,new TGeoTranslation(-0.2,3.6,z));
  
    }
    for ( int i=1; i<=3; i=1+i )
    {
    z= (-1.2*i);
    D->AddNode(comp,i,new TGeoTranslation(-0.2,0.,z));
    D->AddNode(comp,i+3,new TGeoTranslation(-0.2,-1.2,z));
    D->AddNode(comp,i+4,new TGeoTranslation(-0.2,-2.4,z));
    D->AddNode(comp,i+5,new TGeoTranslation(-0.2,-3.6,z));
  
    }
   
    
    for ( int i=1; i<=3; i=1+i )
    {
    z= (1.2*i);

    D->AddNode(comp,i+3,new TGeoTranslation(-0.2,-1.2,z));
    D->AddNode(comp,i+4,new TGeoTranslation(-0.2,-2.4,z));
    D->AddNode(comp,i+5,new TGeoTranslation(-0.2,-3.6,z));
  
    }
  
    for ( int i=1; i<=3; i=1+i )
    {
    z= (-1.2*i);
  
    D->AddNode(comp,i+3,new TGeoTranslation(-0.2,1.2,z));
    D->AddNode(comp,i+4,new TGeoTranslation(-0.2,2.4,z));
    D->AddNode(comp,i+5,new TGeoTranslation(-0.2,3.6,z));
  
    }
    auto pi = TMath::Pi();
 double Rmin=4.2/tan(pi/24);
double Rmax= sqrt((35.28)/(1-1*cos(pi/24)));
// make container ring
auto ring = geom->MakeTube("ring", Vacuum,Rmin,Rmax, 8.4);
// divide ring in sectors that will hold each detector
auto sector = ring->Divide("Sector", 2 , 24,0., 0.);
 
    double dx=(Rmin)+(0.5*9.4);
sector->AddNode(D, 1, new TGeoTranslation(dx,0,0)); // Make sure the sector actually fits the detector
top->AddNode(ring, 1);
// close geometry
geom->CloseGeometry();
gGeoManager->GetMasterVolume()->Draw();
comp->SetLineColor(kBlue);
}