1 /* *************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
21 #include "AliG3toRoot.h"
22 #include "AliG3Volume.h"
23 #include "AliG3Medium.h"
24 #include "AliG3Material.h"
28 #include <TClonesArray.h>
30 #include <TObjArray.h>
32 #include <TRotMatrix.h>
34 #include <TGeometry.h>
38 AliG3toRoot::AliG3toRoot()
41 TFolder* top = gROOT->GetRootFolder ()->AddFolder ("G3toRoot", "Geometry Tree");
42 fTopFolder=top->AddFolder("ALIC", "Top Volume");
43 gROOT->GetListOfBrowsables ()->Add (top, "G3toRoot Folders");
46 fVolumes = new TClonesArray("AliG3Volume",1000);
47 fMaterials = new TClonesArray("AliG3Material",1000);
48 fMedia = new TClonesArray("AliG3Medium",1000);
52 // Store local copy of zebra bank entries
53 TGeant3 *geant3 = (TGeant3*) gMC;
58 fGclink=geant3->Gclink();
59 fGcnum=geant3->Gcnum();
62 fGeometry = new TGeometry("AliceGeom","Detailed Geometry");
64 void AliG3toRoot::G3toRoot()
69 ConvertToRootShapes();
72 TFolder* topFolder = gROOT->GetRootFolder ()->AddFolder ("G3", "G3");
73 TFolder* geoFolder = topFolder->AddFolder("G3toRoot Shapes", " ");
74 geoFolder->Add(fGeometry);
75 gROOT->GetListOfBrowsables ()->Add(geoFolder, "G3toRoot Shapes");
77 TFile* file = new TFile("g3toRootShapes.root", "recreate");
81 file = new TFile("g3toRootFolders.root", "recreate");
87 void AliG3toRoot::ReadGeometryTree()
90 // Copy zebra volume tree into ROOT LisTree
93 char /* *namec, */ *tmp;
100 Int_t newlevel=nlevel;
101 Float_t mpar[3] = {2000., 2000., 2000.};
104 volume = new AliG3Volume("ALIC");
105 volume->SetIdVolume(((TGeant3*)gMC)->VolId("ALIC"));
106 volume->SetIdCopy(0);
108 volume->SetPosition(0.,0.,0.);
109 volume->SetParameters(3,mpar);
110 volume->SetItem(fTopFolder);
111 (*fVolumes)[0]=volume;
113 // Loop over volumes for which information has been collected
115 for (Int_t i=nst; i<nlevel; i++)
117 TFolder *itemi, *item2;
118 // GEANT3 volume number
119 Int_t ivol=TMath::Abs(Volume(i)->GetIdVolume());
121 // icopy=1 normal positioning
122 // icopy>1 positioning with parposp
124 Int_t icopy = Volume(i)->GetIdCopy();
125 // Medium and material number, handle special case of divisions
130 imat=Material(-ivol);
137 pos = Volume(i)->Position(0);
140 // Number of children
141 Int_t nch = NChildren(ivol);
142 strcpy(namec,((TGeant3*)gMC)->VolName(ivol));
144 printf("\n %s has %d children \n ", namec, nch);
146 printf("\n %s has divisions \n ", namec);
149 // Name to be used in ListTree
151 strncpy(vname,namec, 4);
155 sprintf(namec,"%s*%3dPos",namec,icopy);
156 } else if (icopy <0) {
157 sprintf(namec,"%s*%3dDiv",namec,-icopy);
160 itemi=(TFolder*) Volume(i)->GetItem();
164 Volume(i)->SetName(namec);
165 Volume(i)->SetIdMedium(imed);
166 Volume(i)->SetIdMaterial(imat);
169 // Add volume to list tree
172 item2 = AddVolume(new AliG3Volume(*Volume(i)), itemi, namec);
175 fTopFolder->Add(new AliG3Volume(*Volume(i)));
178 // Collect children information
180 // nch < 0: Children by division
183 // Geant volume number
184 Int_t icvol=Child(ivol,1);
186 strcpy(namec,((TGeant3*)gMC)->VolName(-icvol));
188 strncpy(tmp,(char *) &namec, 4);
189 volume = new AliG3Volume(namec);
190 volume->SetIdVolume(-icvol);
192 Int_t jvo = fZlq[fGclink->jvolum-ivol];
193 Int_t jdiv = fZlq[jvo-1];
195 Int_t iaxe = Int_t (fZq[jdiv+1]);
196 // System volume number
197 // Int_t ivin = Int_t (fZq[jdiv+2]);
198 // Number of divisions
199 Int_t ndiv = Int_t (fZq[jdiv+3]);
201 Float_t startc = fZq[jdiv+4];
203 Float_t step = fZq[jdiv+5];
205 Int_t ish = Volume(i)->Shape();
206 Int_t npar = Volume(i)->NParam();
207 // Copy here shape parameters from mother
208 // Expand divisions later (when needed)
211 Volume(i)->Parameters(0, apar);
212 Float_t* par = new Float_t[npar];
213 for (Int_t jj=0; jj<npar; jj++) par[jj]=apar.At(jj);
214 volume->SetIdCopy(-ndiv);
215 volume->SetDivision(ndiv, iaxe, startc, step);
216 volume->SetParameters(npar, par);
217 volume->SetPosition(0.,0.,0.);
218 volume->SetShape(ish);
219 volume->SetRotMatrix(0);
221 volume->SetItem(item2);
222 (*fVolumes)[newlevel]=volume;
225 // Children by positioning
226 } else if (nch > 0) {
228 // Loop over children
229 for (Int_t j=0; j<nch; j++)
231 Int_t jvo = fZlq[fGclink->jvolum-ivol];
232 Int_t jin = fZlq[jvo-j-1];
233 Int_t ivin = Int_t (fZq[jin + 2 ]);
234 Int_t jvin = fZlq[fGclink->jvolum - ivin];
235 Int_t ish = Int_t (fZq[jvin + 2]);
236 Int_t irot = Int_t(fZq[jin +4]);
237 Float_t x = fZq[jin +5];
238 Float_t y = fZq[jin +6];
239 Float_t z = fZq[jin +7];
240 Int_t ndata = Int_t(fZiq[jin-1]);
244 // Get shape parameters
246 // parp or normal positioning ?
248 npar = Int_t (fZq[jvin+5]);
249 par = new Float_t[npar];
251 for(Int_t jj=0; jj<npar; jj++)
252 par[jj] = fZq[jvin+7+jj];
255 npar = Int_t (fZq[jin+9]);
256 par = new Float_t[npar];
257 for(Int_t jj=0;jj<npar;jj++)
258 par[jj]=fZq[jin+10+jj];
261 // Find out if this volume was already positioned and count copies
262 Int_t icvol=Child(ivol,j+1);
263 icvol = TMath::Abs(icvol);
264 Bool_t inList=kFALSE;
265 AliG3Volume* copy0=0;
267 for (Int_t k=0; k<nnew; k++) {
269 Volume(newlevel-k-1)->GetIdVolume())
271 copy0 = Volume(newlevel-k-1);
272 Volume(newlevel-k-1)->AddCopy();
280 strcpy(namec,((TGeant3*)gMC)->VolName(icvol));
282 strncpy(tmp,(char *) &namec, 4);
283 volume = new AliG3Volume(namec);
284 volume->SetPosition(x,y,z);
285 volume->SetShape(ish);
286 volume->SetParameters(npar, par);
287 volume->SetRotMatrix(irot);
288 if (ndata != 8) volume->SetPosp(kTRUE);
289 volume->SetIdVolume(icvol);
290 volume->SetIdCopy(1);
292 volume->SetItem(item2);
294 (*fVolumes)[newlevel]=volume;
298 copy0->AddCopy(volume);
303 // Move one level deaper
309 void AliG3toRoot::ReadMaterials()
312 // Puts media and material names into ComboBox and
313 // collects material information
315 Float_t a, z, dens, radl, absl;
316 a=z=dens=radl=absl=-1;
318 Int_t imat, isvol, ifield;
319 Float_t fieldm, tmaxfd, stemax, deemax, epsil, stmin;
324 char natmed[21], namate[21];
329 for(Int_t itm=1;itm<=fGcnum->ntmed;itm++) {
330 Int_t jtm = fZlq[fGclink->jtmed-itm];
334 // Get medium parameters
336 Gftmed(itm, natmed, imat, isvol, ifield, fieldm,
337 tmaxfd, stemax, deemax, epsil, stmin, ubuf, &nwbuf);
338 strncpy(natmed,(char*)&fZiq[jtm+1],20);
341 // Create new medium object
342 AliG3Medium * medium =
343 new AliG3Medium(itm, imat, natmed, isvol, ifield, fieldm,
344 tmaxfd, stemax, deemax, epsil, stmin);
345 (*fMedia)[nEntries-1]=medium;
346 { //Begin local scope for j
347 for (Int_t j=1; j<=22; j++) {
348 medium->SetPar(j,Cut(itm,j));
350 } //End local scope for j
351 { //Begin local scope for j
352 for (Int_t j=23; j<=26; j++) {
353 medium->SetPar(j,Cut(itm,j+3));
355 } //End local scope for j
356 { //Begin local scope for j
357 for (Int_t j=27; j<=29; j++) {
358 medium->SetPar(j,Cut(itm,j+4));
360 } //End local scope for j
362 // Associated material
363 imat = Int_t (fZq[jtm+6]);
364 Int_t jma = Int_t (fZlq[fGclink->jmate-imat]);
366 // Get material parameters
367 ((TGeant3*)(gMC))->Gfmate (imat,namate,a,z,dens,radl,absl,par,npar);
368 strncpy(namate,(char *)&fZiq[jma+1],20);
371 // Create new material object
372 AliG3Material* material = new AliG3Material(namate, " ", a,z,dens,radl,absl);
373 material->SetId(imat);
375 (*fMaterials)[nEntries-1] = material;
381 void AliG3toRoot::ReadRotations()
383 // Read rotation matrices
387 if(fGclink->jrotm) nrot = Int_t(fZiq[fGclink->jrotm-2]);
389 fRotations = new TObjArray(nrot);
390 for(irm=1;irm<=nrot;irm++) {
391 jrm = fZlq[fGclink->jrotm-irm];
392 sprintf(name, "R%d", irm);
393 (*fRotations)[irm-1] =
394 new TRotMatrix(name, "Rotation", fZq[jrm+11], fZq[jrm+12], fZq[jrm+13],
395 fZq[jrm+14], fZq[jrm+15], fZq[jrm+16]);
400 Int_t AliG3toRoot::NChildren(Int_t idvol)
403 // Return number of children for volume idvol
404 Int_t jvo = fZlq[fGclink->jvolum-idvol];
405 Int_t nin = Int_t(fZq[jvo+3]);
409 Int_t AliG3toRoot::Child(Int_t idvol, Int_t idc)
412 // Return GEANT id of child number idc of volume idvol
413 Int_t jvo = fZlq[fGclink->jvolum-idvol];
415 Int_t jin = fZlq[jvo-nin];
416 Int_t numb = Int_t (fZq[jin +3]);
418 return -Int_t(fZq[jin+2]);
420 return Int_t(fZq[jin+2]);
424 Int_t AliG3toRoot::Medium(Int_t idvol)
427 // Return medium number for volume idvol.
428 // If idvol is negative the volume results from a division.
431 Int_t jvo = fZlq[fGclink->jvolum-idvol];
432 imed = Int_t(fZq[jvo+4]);
435 Int_t jdiv = fZlq[fGclink->jvolum-idvol];
436 Int_t ivin = Int_t ( fZq[jdiv+2]);
437 Int_t jvin = fZlq[fGclink->jvolum-ivin];
438 imed = Int_t (fZq[jvin+4]);
443 Int_t AliG3toRoot::Material(Int_t idvol)
445 // Return material number for volume idvol.
446 // If idvol is negative the volume results from a division.
448 Int_t imed=Medium(idvol);
449 Int_t jtm = fZlq[fGclink->jtmed-imed];
450 return Int_t (fZq[jtm+6]);
454 Float_t AliG3toRoot::Cut(Int_t imed, Int_t icut)
456 // Return cuts icut for medium idmed
458 Int_t jtm = fZlq[fGclink->jtmed-imed];
460 // Have the defaults been modified ??
461 Int_t jtmn = fZlq[jtm];
469 return Float_t (fZq[jtm+icut]);
472 TFolder* AliG3toRoot::AddVolume(TObject * obj, TFolder *parent, const char* name)
474 // Add item to the list tree
475 TFolder* newFolder = parent->AddFolder(name, "volume");
480 AliG3Volume* AliG3toRoot::Volume(Int_t id)
484 return (AliG3Volume *) (fVolumes->UncheckedAt(id));
488 void AliG3toRoot::ConvertToRootShapes(TFolder *item, AliNode** node, Int_t nNodes)
490 // Convert the geometry represented by TFolders into root shapes
505 if (nNodes == 0) nNodes = 1;
507 TList* folders = (TList*) item->GetListOfFolders();
511 volume = ((AliG3Volume *) item->FindObject(item->GetName()));
512 Int_t ncopy = volume->NCopies();
513 AliNode** newnode = new AliNode*[(ncopy+1)*nNodes];
515 for (Int_t ino=0; ino<nNodes; ino++) {
517 pos = volume->Position(0);
518 irot = volume->RotMatrix();
519 imat = volume->Material();
521 sprintf(nameV,"v%s%d", volume->GetName(), npos);
522 sprintf(nameN,"%s%d" , volume->GetName(), npos);
525 imat = volume->Material();
526 Int_t nmat = fMaterials->GetEntriesFast();
527 AliG3Material* mat=0;
529 for (Int_t mati=0; mati<nmat; mati++) {
530 mat = (AliG3Material*)
531 (fMaterials->UncheckedAt(mati));
532 if ((mat->Id())==imat) break;
536 volume->CreateTShape(nameV, mat);
540 newnode[npos] = new AliNode(nameN," ",nameV, pos[0], pos[1], pos[2]);
541 newnode[npos]->SetDivision(volume->Ndiv(), volume->Axis(),
542 volume->Step(), volume->StartC());
543 if (irot > 0) newnode[npos]->SetMatrix((TRotMatrix*) (*fRotations)[irot-1]);
547 new TMaterial("void","Vacuum",0,0,0); //Everything is void
548 TBRIK *brik = new TBRIK("D_alice","alice volume",
549 "void",2000,2000,3000);
550 brik->SetVisibility(0);
551 newnode[npos] = new AliNode("alice","alice","D_alice");
556 for (Int_t icop = 0; icop < ncopy; icop++) {
557 AliG3Volume* copy = volume->Copy(icop);
559 sprintf(nameN,"%s%d" , volume->GetName(), icop+1);
561 sprintf(nameV,"v%s%d", volume->GetName(), icop+1);
562 volume->CreateTShape(nameV, mat);
565 pos = copy->Position(0);
566 irot = copy->RotMatrix();
567 newnode[npos] = new AliNode(nameN," ",nameV, pos[0], pos[1], pos[2]);
568 newnode[npos]->SetDivision(volume->Ndiv(), volume->Axis(),
569 volume->Step(), volume->StartC());
570 if (irot >0) newnode[npos]->SetMatrix((TRotMatrix*) (*fRotations)[irot-1]);
577 while ((obj = next()))
579 if ((AliG3Volume*) obj == volume) continue;
580 item = (TFolder*) obj;
582 ConvertToRootShapes(item, newnode, npos);
585 // Expand divisions of demand
586 if (fExpand) ExpandDivisions();
589 void AliG3toRoot::ExpandDivisions(AliNode* node)
591 // Expand volume divisions
597 node = (AliNode*) fGeometry->GetNode("alice");
600 if (!top && node->Ndiv() > 0 && node->Axis()>0) {
602 node->ExpandDivisions();
603 node->GetParent()->RecursiveRemove(node);
607 TList* sons = node->GetListOfNodes();
611 while((son = (AliNode*)next())) {
612 ExpandDivisions(son);