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 **************************************************************************/
18 Revision 1.2 2001/08/30 09:32:30 hristov
19 The operator[] is replaced by At() or AddAt() in case of TObjArray.
21 Revision 1.1 2001/07/09 11:43:01 morsch
22 Class Responsible for G3 -> Root geometry conversion.
27 #include "AliG3toRoot.h"
28 #include "AliG3Volume.h"
29 #include "AliG3Medium.h"
30 #include "AliG3Material.h"
33 #include <TClonesArray.h>
35 #include <TObjArray.h>
37 #include <TRotMatrix.h>
39 #include <TGeometry.h>
43 AliG3toRoot::AliG3toRoot()
46 TFolder* top = gROOT->GetRootFolder ()->AddFolder ("G3toRoot", "Geometry Tree");
47 fTopFolder=top->AddFolder("ALIC", "Top Volume");
48 gROOT->GetListOfBrowsables ()->Add (top, "G3toRoot Folders");
51 fVolumes = new TClonesArray("AliG3Volume",1000);
52 fMaterials = new TClonesArray("AliG3Material",1000);
53 fMedia = new TClonesArray("AliG3Medium",1000);
57 // Store local copy of zebra bank entries
58 TGeant3 *geant3 = (TGeant3*) gMC;
63 fGclink=geant3->Gclink();
64 fGcnum=geant3->Gcnum();
67 fGeometry = new TGeometry("AliceGeom","Detailed Geometry");
69 void AliG3toRoot::G3toRoot()
74 ConvertToRootShapes();
77 TFolder* topFolder = gROOT->GetRootFolder ()->AddFolder ("G3", "G3");
78 TFolder* geoFolder = topFolder->AddFolder("G3toRoot Shapes", " ");
79 geoFolder->Add(fGeometry);
80 gROOT->GetListOfBrowsables ()->Add(geoFolder, "G3toRoot Shapes");
82 TFile* file = new TFile("g3toRootShapes.root", "recreate");
86 file = new TFile("g3toRootFolders.root", "recreate");
92 void AliG3toRoot::ReadGeometryTree()
95 // Copy zebra volume tree into ROOT LisTree
98 char /* *namec, */ *tmp;
105 Int_t newlevel=nlevel;
106 Float_t mpar[3] = {2000., 2000., 2000.};
109 volume = new AliG3Volume("ALIC");
110 volume->SetIdVolume(((TGeant3*)gMC)->VolId("ALIC"));
111 volume->SetIdCopy(0);
113 volume->SetPosition(0.,0.,0.);
114 volume->SetParameters(3,mpar);
115 volume->SetItem(fTopFolder);
116 (*fVolumes)[0]=volume;
118 // Loop over volumes for which information has been collected
120 for (Int_t i=nst; i<nlevel; i++)
122 TFolder *itemi, *item2;
123 // GEANT3 volume number
124 Int_t ivol=TMath::Abs(Volume(i)->GetIdVolume());
126 // icopy=1 normal positioning
127 // icopy>1 positioning with parposp
129 Int_t icopy = Volume(i)->GetIdCopy();
130 // Medium and material number, handle special case of divisions
135 imat=Material(-ivol);
142 pos = Volume(i)->Position(0);
145 // Number of children
146 Int_t nch = NChildren(ivol);
147 strcpy(namec,((TGeant3*)gMC)->VolName(ivol));
149 printf("\n %s has %d children \n ", namec, nch);
151 printf("\n %s has divisions \n ", namec);
154 // Name to be used in ListTree
156 strncpy(vname,namec, 4);
160 sprintf(namec,"%s*%3dPos",namec,icopy);
161 } else if (icopy <0) {
162 sprintf(namec,"%s*%3dDiv",namec,-icopy);
165 itemi=(TFolder*) Volume(i)->GetItem();
169 Volume(i)->SetName(namec);
170 Volume(i)->SetIdMedium(imed);
171 Volume(i)->SetIdMaterial(imat);
174 // Add volume to list tree
177 item2 = AddVolume(new AliG3Volume(*Volume(i)), itemi, namec);
180 fTopFolder->Add(new AliG3Volume(*Volume(i)));
183 // Collect children information
185 // nch < 0: Children by division
188 // Geant volume number
189 Int_t icvol=Child(ivol,1);
191 strcpy(namec,((TGeant3*)gMC)->VolName(-icvol));
193 strncpy(tmp,(char *) &namec, 4);
194 volume = new AliG3Volume(namec);
195 volume->SetIdVolume(-icvol);
197 Int_t jvo = fZlq[fGclink->jvolum-ivol];
198 Int_t jdiv = fZlq[jvo-1];
200 Int_t iaxe = Int_t (fZq[jdiv+1]);
201 // System volume number
202 // Int_t ivin = Int_t (fZq[jdiv+2]);
203 // Number of divisions
204 Int_t ndiv = Int_t (fZq[jdiv+3]);
206 Float_t startc = fZq[jdiv+4];
208 Float_t step = fZq[jdiv+5];
210 Int_t ish = Volume(i)->Shape();
211 Int_t npar = Volume(i)->NParam();
212 // Copy here shape parameters from mother
213 // Expand divisions later (when needed)
216 Volume(i)->Parameters(0, apar);
217 Float_t* par = new Float_t[npar];
218 for (Int_t jj=0; jj<npar; jj++) par[jj]=apar.At(jj);
219 volume->SetIdCopy(-ndiv);
220 volume->SetDivision(ndiv, iaxe, startc, step);
221 volume->SetParameters(npar, par);
222 volume->SetPosition(0.,0.,0.);
223 volume->SetShape(ish);
224 volume->SetRotMatrix(0);
226 volume->SetItem(item2);
227 (*fVolumes)[newlevel]=volume;
230 // Children by positioning
231 } else if (nch > 0) {
233 // Loop over children
234 for (Int_t j=0; j<nch; j++)
236 Int_t jvo = fZlq[fGclink->jvolum-ivol];
237 Int_t jin = fZlq[jvo-j-1];
238 Int_t ivin = Int_t (fZq[jin + 2 ]);
239 Int_t jvin = fZlq[fGclink->jvolum - ivin];
240 Int_t ish = Int_t (fZq[jvin + 2]);
241 Int_t irot = Int_t(fZq[jin +4]);
242 Float_t x = fZq[jin +5];
243 Float_t y = fZq[jin +6];
244 Float_t z = fZq[jin +7];
245 Int_t ndata = Int_t(fZiq[jin-1]);
249 // Get shape parameters
251 // parp or normal positioning ?
253 npar = Int_t (fZq[jvin+5]);
254 par = new Float_t[npar];
256 for(Int_t jj=0; jj<npar; jj++)
257 par[jj] = fZq[jvin+7+jj];
260 npar = Int_t (fZq[jin+9]);
261 par = new Float_t[npar];
262 for(Int_t jj=0;jj<npar;jj++)
263 par[jj]=fZq[jin+10+jj];
266 // Find out if this volume was already positioned and count copies
267 Int_t icvol=Child(ivol,j+1);
268 icvol = TMath::Abs(icvol);
269 Bool_t inList=kFALSE;
270 AliG3Volume* copy0=0;
272 for (Int_t k=0; k<nnew; k++) {
274 Volume(newlevel-k-1)->GetIdVolume())
276 copy0 = Volume(newlevel-k-1);
277 Volume(newlevel-k-1)->AddCopy();
285 strcpy(namec,((TGeant3*)gMC)->VolName(icvol));
287 strncpy(tmp,(char *) &namec, 4);
288 volume = new AliG3Volume(namec);
289 volume->SetPosition(x,y,z);
290 volume->SetShape(ish);
291 volume->SetParameters(npar, par);
292 volume->SetRotMatrix(irot);
293 if (ndata != 8) volume->SetPosp(kTRUE);
294 volume->SetIdVolume(icvol);
295 volume->SetIdCopy(1);
297 volume->SetItem(item2);
299 (*fVolumes)[newlevel]=volume;
303 copy0->AddCopy(volume);
308 // Move one level deaper
314 void AliG3toRoot::ReadMaterials()
317 // Puts media and material names into ComboBox and
318 // collects material information
320 Float_t a, z, dens, radl, absl;
321 a=z=dens=radl=absl=-1;
323 Int_t imat, isvol, ifield;
324 Float_t fieldm, tmaxfd, stemax, deemax, epsil, stmin;
329 char natmed[21], namate[21];
334 for(Int_t itm=1;itm<=fGcnum->ntmed;itm++) {
335 Int_t jtm = fZlq[fGclink->jtmed-itm];
339 // Get medium parameters
341 Gftmed(itm, natmed, imat, isvol, ifield, fieldm,
342 tmaxfd, stemax, deemax, epsil, stmin, ubuf, &nwbuf);
343 strncpy(natmed,(char*)&fZiq[jtm+1],20);
346 // Create new medium object
347 AliG3Medium * medium =
348 new AliG3Medium(itm, imat, natmed, isvol, ifield, fieldm,
349 tmaxfd, stemax, deemax, epsil, stmin);
350 (*fMedia)[nEntries-1]=medium;
351 { //Begin local scope for j
352 for (Int_t j=1; j<=22; j++) {
353 medium->SetPar(j,Cut(itm,j));
355 } //End local scope for j
356 { //Begin local scope for j
357 for (Int_t j=23; j<=26; j++) {
358 medium->SetPar(j,Cut(itm,j+3));
360 } //End local scope for j
361 { //Begin local scope for j
362 for (Int_t j=27; j<=29; j++) {
363 medium->SetPar(j,Cut(itm,j+4));
365 } //End local scope for j
367 // Associated material
368 imat = Int_t (fZq[jtm+6]);
369 Int_t jma = Int_t (fZlq[fGclink->jmate-imat]);
371 // Get material parameters
372 ((TGeant3*)(gMC))->Gfmate (imat,namate,a,z,dens,radl,absl,par,npar);
373 strncpy(namate,(char *)&fZiq[jma+1],20);
376 // Create new material object
377 AliG3Material* material = new AliG3Material(namate, " ", a,z,dens,radl,absl);
378 material->SetId(imat);
380 (*fMaterials)[nEntries-1] = material;
386 void AliG3toRoot::ReadRotations()
388 // Read rotation matrices
392 if(fGclink->jrotm) nrot = Int_t(fZiq[fGclink->jrotm-2]);
394 fRotations = new TObjArray(nrot);
395 for(irm=1;irm<=nrot;irm++) {
396 jrm = fZlq[fGclink->jrotm-irm];
397 sprintf(name, "R%d", irm);
398 //PH (*fRotations)[irm-1] =
399 //PH new TRotMatrix(name, "Rotation", fZq[jrm+11], fZq[jrm+12], fZq[jrm+13],
400 //PH fZq[jrm+14], fZq[jrm+15], fZq[jrm+16]);
402 new TRotMatrix(name, "Rotation", fZq[jrm+11], fZq[jrm+12], fZq[jrm+13],
403 fZq[jrm+14], fZq[jrm+15], fZq[jrm+16]), irm-1);
408 Int_t AliG3toRoot::NChildren(Int_t idvol)
411 // Return number of children for volume idvol
412 Int_t jvo = fZlq[fGclink->jvolum-idvol];
413 Int_t nin = Int_t(fZq[jvo+3]);
417 Int_t AliG3toRoot::Child(Int_t idvol, Int_t idc)
420 // Return GEANT id of child number idc of volume idvol
421 Int_t jvo = fZlq[fGclink->jvolum-idvol];
423 Int_t jin = fZlq[jvo-nin];
424 Int_t numb = Int_t (fZq[jin +3]);
426 return -Int_t(fZq[jin+2]);
428 return Int_t(fZq[jin+2]);
432 Int_t AliG3toRoot::Medium(Int_t idvol)
435 // Return medium number for volume idvol.
436 // If idvol is negative the volume results from a division.
439 Int_t jvo = fZlq[fGclink->jvolum-idvol];
440 imed = Int_t(fZq[jvo+4]);
443 Int_t jdiv = fZlq[fGclink->jvolum-idvol];
444 Int_t ivin = Int_t ( fZq[jdiv+2]);
445 Int_t jvin = fZlq[fGclink->jvolum-ivin];
446 imed = Int_t (fZq[jvin+4]);
451 Int_t AliG3toRoot::Material(Int_t idvol)
453 // Return material number for volume idvol.
454 // If idvol is negative the volume results from a division.
456 Int_t imed=Medium(idvol);
457 Int_t jtm = fZlq[fGclink->jtmed-imed];
458 return Int_t (fZq[jtm+6]);
462 Float_t AliG3toRoot::Cut(Int_t imed, Int_t icut)
464 // Return cuts icut for medium idmed
466 Int_t jtm = fZlq[fGclink->jtmed-imed];
468 // Have the defaults been modified ??
469 Int_t jtmn = fZlq[jtm];
477 return Float_t (fZq[jtm+icut]);
480 TFolder* AliG3toRoot::AddVolume(TObject * obj, TFolder *parent, const char* name)
482 // Add item to the list tree
483 TFolder* newFolder = parent->AddFolder(name, "volume");
488 AliG3Volume* AliG3toRoot::Volume(Int_t id)
492 return (AliG3Volume *) (fVolumes->UncheckedAt(id));
496 void AliG3toRoot::ConvertToRootShapes(TFolder *item, AliNode** node, Int_t nNodes)
498 // Convert the geometry represented by TFolders into root shapes
513 if (nNodes == 0) nNodes = 1;
515 TList* folders = (TList*) item->GetListOfFolders();
519 volume = ((AliG3Volume *) item->FindObject(item->GetName()));
520 Int_t ncopy = volume->NCopies();
521 AliNode** newnode = new AliNode*[(ncopy+1)*nNodes];
523 for (Int_t ino=0; ino<nNodes; ino++) {
525 pos = volume->Position(0);
526 irot = volume->RotMatrix();
527 imat = volume->Material();
529 sprintf(nameV,"v%s%d", volume->GetName(), npos);
530 sprintf(nameN,"%s%d" , volume->GetName(), npos);
533 imat = volume->Material();
534 Int_t nmat = fMaterials->GetEntriesFast();
535 AliG3Material* mat=0;
537 for (Int_t mati=0; mati<nmat; mati++) {
538 mat = (AliG3Material*)
539 (fMaterials->UncheckedAt(mati));
540 if ((mat->Id())==imat) break;
544 volume->CreateTShape(nameV, mat);
548 newnode[npos] = new AliNode(nameN," ",nameV, pos[0], pos[1], pos[2]);
549 newnode[npos]->SetDivision(volume->Ndiv(), volume->Axis(),
550 volume->Step(), volume->StartC());
551 if (irot > 0) newnode[npos]->SetMatrix((TRotMatrix*) (*fRotations)[irot-1]);
555 new TMaterial("void","Vacuum",0,0,0); //Everything is void
556 TBRIK *brik = new TBRIK("D_alice","alice volume",
557 "void",2000,2000,3000);
558 brik->SetVisibility(0);
559 newnode[npos] = new AliNode("alice","alice","D_alice");
564 for (Int_t icop = 0; icop < ncopy; icop++) {
565 AliG3Volume* copy = volume->Copy(icop);
567 sprintf(nameN,"%s%d" , volume->GetName(), icop+1);
569 sprintf(nameV,"v%s%d", volume->GetName(), icop+1);
570 volume->CreateTShape(nameV, mat);
573 pos = copy->Position(0);
574 irot = copy->RotMatrix();
575 newnode[npos] = new AliNode(nameN," ",nameV, pos[0], pos[1], pos[2]);
576 newnode[npos]->SetDivision(volume->Ndiv(), volume->Axis(),
577 volume->Step(), volume->StartC());
578 if (irot >0) newnode[npos]->SetMatrix((TRotMatrix*) (*fRotations)[irot-1]);
585 while ((obj = next()))
587 if ((AliG3Volume*) obj == volume) continue;
588 item = (TFolder*) obj;
590 ConvertToRootShapes(item, newnode, npos);
593 // Expand divisions of demand
594 if (fExpand) ExpandDivisions();
597 void AliG3toRoot::ExpandDivisions(AliNode* node)
599 // Expand volume divisions
605 node = (AliNode*) fGeometry->GetNode("alice");
608 if (!top && node->Ndiv() > 0 && node->Axis()>0) {
610 node->ExpandDivisions();
611 node->GetParent()->RecursiveRemove(node);
615 TList* sons = node->GetListOfNodes();
619 while((son = (AliNode*)next())) {
620 ExpandDivisions(son);