]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TGeant3/AliG3toRoot.cxx
Minor bugs in the definition of the bending impact parameter corrected (thanks to...
[u/mrichter/AliRoot.git] / TGeant3 / AliG3toRoot.cxx
CommitLineData
db475b14 1/* *************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/*
17$Log$
8e33b38c 18Revision 1.2 2001/08/30 09:32:30 hristov
19The operator[] is replaced by At() or AddAt() in case of TObjArray.
20
350743f0 21Revision 1.1 2001/07/09 11:43:01 morsch
22Class Responsible for G3 -> Root geometry conversion.
23
db475b14 24*/
25
26
27#include "AliG3toRoot.h"
28#include "AliG3Volume.h"
29#include "AliG3Medium.h"
30#include "AliG3Material.h"
31#include "AliNode.h"
db475b14 32
33#include <TClonesArray.h>
34#include <TList.h>
35#include <TObjArray.h>
36#include <TFolder.h>
37#include <TRotMatrix.h>
38#include <TFile.h>
39#include <TGeometry.h>
40#include <TBRIK.h>
41
42ClassImp(AliG3toRoot)
43 AliG3toRoot::AliG3toRoot()
44{
45// Constructor
46 TFolder* top = gROOT->GetRootFolder ()->AddFolder ("G3toRoot", "Geometry Tree");
47 fTopFolder=top->AddFolder("ALIC", "Top Volume");
48 gROOT->GetListOfBrowsables ()->Add (top, "G3toRoot Folders");
49
50//
51 fVolumes = new TClonesArray("AliG3Volume",1000);
52 fMaterials = new TClonesArray("AliG3Material",1000);
53 fMedia = new TClonesArray("AliG3Medium",1000);
54 fRotations = 0;
55 fExpand = 0;
56
57// Store local copy of zebra bank entries
58 TGeant3 *geant3 = (TGeant3*) gMC;
59 if (geant3) {
60 fZlq=geant3->Lq();
61 fZq=geant3->Q();
62 fZiq=geant3->Iq();
63 fGclink=geant3->Gclink();
64 fGcnum=geant3->Gcnum();
65 }
66// Geometry
67 fGeometry = new TGeometry("AliceGeom","Detailed Geometry");
68}
69void AliG3toRoot::G3toRoot()
70{
71 ReadGeometryTree();
72 ReadMaterials();
73 ReadRotations();
74 ConvertToRootShapes();
75
76//
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");
81
82 TFile* file = new TFile("g3toRootShapes.root", "recreate");
83 geoFolder->Write();
84 file->Close();
85
86 file = new TFile("g3toRootFolders.root", "recreate");
87 fTopFolder->Write();
88 file->Close();
89
90}
91
92void AliG3toRoot::ReadGeometryTree()
93{
94//
95// Copy zebra volume tree into ROOT LisTree
96//
97 char *vname;
98 char /* *namec, */ *tmp;
99 char namec[30];
100
101 AliG3Volume *volume;
102
103 Int_t nst=0;
104 Int_t nlevel=1;
105 Int_t newlevel=nlevel;
106 Float_t mpar[3] = {2000., 2000., 2000.};
107
108
109 volume = new AliG3Volume("ALIC");
110 volume->SetIdVolume(((TGeant3*)gMC)->VolId("ALIC"));
111 volume->SetIdCopy(0);
112 volume->SetShape(1);
113 volume->SetPosition(0.,0.,0.);
114 volume->SetParameters(3,mpar);
115 volume->SetItem(fTopFolder);
116 (*fVolumes)[0]=volume;
117//
118// Loop over volumes for which information has been collected
119 while(nlevel>nst) {
120 for (Int_t i=nst; i<nlevel; i++)
121 {
122 TFolder *itemi, *item2;
123// GEANT3 volume number
124 Int_t ivol=TMath::Abs(Volume(i)->GetIdVolume());
125// Copy number
126// icopy=1 normal positioning
127// icopy>1 positioning with parposp
128// icopy<0 division
129 Int_t icopy = Volume(i)->GetIdCopy();
130// Medium and material number, handle special case of divisions
131 Int_t imat, imed;
132
133 if (icopy <0) {
134 imed=Medium(-ivol);
135 imat=Material(-ivol);
136 } else {
137 imed=Medium(ivol);
138 imat=Material(ivol);
139 }
140
141 TArrayF pos;
142 pos = Volume(i)->Position(0);
143
144//
145// Number of children
146 Int_t nch = NChildren(ivol);
147 strcpy(namec,((TGeant3*)gMC)->VolName(ivol));
148 if (nch >= 0) {
149 printf("\n %s has %d children \n ", namec, nch);
150 } else {
151 printf("\n %s has divisions \n ", namec);
152 }
153//
154// Name to be used in ListTree
155 vname = new char[5];
156 strncpy(vname,namec, 4);
157 vname[4]='\0';
158
159 if (icopy >1) {
160 sprintf(namec,"%s*%3dPos",namec,icopy);
161 } else if (icopy <0) {
162 sprintf(namec,"%s*%3dDiv",namec,-icopy);
163 }
164 if (i>0) {
165 itemi=(TFolder*) Volume(i)->GetItem();
166 } else {
167 itemi=fTopFolder;
168 }
169 Volume(i)->SetName(namec);
170 Volume(i)->SetIdMedium(imed);
171 Volume(i)->SetIdMaterial(imat);
172
173//
174// Add volume to list tree
175
176 if (i>0) {
177 item2 = AddVolume(new AliG3Volume(*Volume(i)), itemi, namec);
178 } else {
179 item2 = fTopFolder;
180 fTopFolder->Add(new AliG3Volume(*Volume(i)));
181 }
182//
183// Collect children information
184//
185// nch < 0: Children by division
186 if (nch < 0) {
187//
188// Geant volume number
189 Int_t icvol=Child(ivol,1);
190// Name
191 strcpy(namec,((TGeant3*)gMC)->VolName(-icvol));
192 tmp = new char[4];
193 strncpy(tmp,(char *) &namec, 4);
194 volume = new AliG3Volume(namec);
195 volume->SetIdVolume(-icvol);
196
197 Int_t jvo = fZlq[fGclink->jvolum-ivol];
198 Int_t jdiv = fZlq[jvo-1];
199// Axis
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]);
205// Start value
206 Float_t startc = fZq[jdiv+4];
207// Step
208 Float_t step = fZq[jdiv+5];
209
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)
214 TArrayF apar;
215 apar.Set(npar);
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);
225// Link to mother
226 volume->SetItem(item2);
227 (*fVolumes)[newlevel]=volume;
228 newlevel++;
229//
230// Children by positioning
231 } else if (nch > 0) {
232 Int_t nnew=0;
233// Loop over children
234 for (Int_t j=0; j<nch; j++)
235 {
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]);
246 Int_t npar;
247 Float_t* par;
248//
249// Get shape parameters
250//
251// parp or normal positioning ?
252 if (ndata == 8) {
253 npar = Int_t (fZq[jvin+5]);
254 par = new Float_t[npar];
255 if (npar>0) {
256 for(Int_t jj=0; jj<npar; jj++)
257 par[jj] = fZq[jvin+7+jj];
258 }
259 } else {
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];
264 }
265//
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;
271
272 for (Int_t k=0; k<nnew; k++) {
273 if (icvol==
274 Volume(newlevel-k-1)->GetIdVolume())
275 {
276 copy0 = Volume(newlevel-k-1);
277 Volume(newlevel-k-1)->AddCopy();
278 inList=kTRUE;
279 }
280 }
281//
282// New child
283//
284// Name
285 strcpy(namec,((TGeant3*)gMC)->VolName(icvol));
286 tmp = new char[4];
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);
296// Link to mother
297 volume->SetItem(item2);
298 if (!inList) {
299 (*fVolumes)[newlevel]=volume;
300 newlevel++;
301 nnew++;
302 } else {
303 copy0->AddCopy(volume);
304 }
305 }
306 }
307 }
308// Move one level deaper
309 nst=nlevel;
310 nlevel=newlevel;
311 }
312}
313
314void AliG3toRoot::ReadMaterials()
315{
316//
317// Puts media and material names into ComboBox and
318// collects material information
319//
320 Float_t a, z, dens, radl, absl;
321 a=z=dens=radl=absl=-1;
322 Int_t npar=0;
323 Int_t imat, isvol, ifield;
324 Float_t fieldm, tmaxfd, stemax, deemax, epsil, stmin;
325 Float_t par[50];
326 Float_t ubuf[50];
327 Int_t nwbuf;
328
329 char natmed[21], namate[21];
330//
331// Loop over media
332 Int_t nEntries=0;
333
334 for(Int_t itm=1;itm<=fGcnum->ntmed;itm++) {
335 Int_t jtm = fZlq[fGclink->jtmed-itm];
336 if (jtm > 0) {
337 nEntries++;
338//
339// Get medium parameters
340 ((TGeant3*)(gMC))->
341 Gftmed(itm, natmed, imat, isvol, ifield, fieldm,
342 tmaxfd, stemax, deemax, epsil, stmin, ubuf, &nwbuf);
343 strncpy(natmed,(char*)&fZiq[jtm+1],20);
344 natmed[20]='\0';
345//
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));
354 }
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));
359 }
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));
364 }
365 } //End local scope for j
366//
367// Associated material
368 imat = Int_t (fZq[jtm+6]);
369 Int_t jma = Int_t (fZlq[fGclink->jmate-imat]);
370//
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);
374 namate[20]='\0';
375//
376// Create new material object
377 AliG3Material* material = new AliG3Material(namate, " ", a,z,dens,radl,absl);
378 material->SetId(imat);
379
380 (*fMaterials)[nEntries-1] = material;
381 material->Dump();
382 }
383 }
384}
385
386void AliG3toRoot::ReadRotations()
387{
388// Read rotation matrices
389 Int_t nrot = 0;
390 Int_t irm, jrm;
391 char name[9];
392 if(fGclink->jrotm) nrot = Int_t(fZiq[fGclink->jrotm-2]);
393 if (nrot) {
394 fRotations = new TObjArray(nrot);
395 for(irm=1;irm<=nrot;irm++) {
396 jrm = fZlq[fGclink->jrotm-irm];
397 sprintf(name, "R%d", irm);
350743f0 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]);
401 fRotations->AddAt(
db475b14 402 new TRotMatrix(name, "Rotation", fZq[jrm+11], fZq[jrm+12], fZq[jrm+13],
350743f0 403 fZq[jrm+14], fZq[jrm+15], fZq[jrm+16]), irm-1);
db475b14 404 }
405 }
406}
407
408Int_t AliG3toRoot::NChildren(Int_t idvol)
409{
410//
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]);
414 return nin;
415}
416
417Int_t AliG3toRoot::Child(Int_t idvol, Int_t idc)
418{
419//
420// Return GEANT id of child number idc of volume idvol
421 Int_t jvo = fZlq[fGclink->jvolum-idvol];
422 Int_t nin=idc;
423 Int_t jin = fZlq[jvo-nin];
424 Int_t numb = Int_t (fZq[jin +3]);
425 if (numb > 1) {
426 return -Int_t(fZq[jin+2]);
427 } else {
428 return Int_t(fZq[jin+2]);
429 }
430}
431
432Int_t AliG3toRoot::Medium(Int_t idvol)
433{
434//
435// Return medium number for volume idvol.
436// If idvol is negative the volume results from a division.
437 Int_t imed;
438 if (idvol > 0) {
439 Int_t jvo = fZlq[fGclink->jvolum-idvol];
440 imed = Int_t(fZq[jvo+4]);
441 } else {
442 idvol=-idvol;
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]);
447 }
448 return imed;
449}
450
451Int_t AliG3toRoot::Material(Int_t idvol)
452{
453// Return material number for volume idvol.
454// If idvol is negative the volume results from a division.
455
456 Int_t imed=Medium(idvol);
457 Int_t jtm = fZlq[fGclink->jtmed-imed];
458 return Int_t (fZq[jtm+6]);
459}
460
461
462Float_t AliG3toRoot::Cut(Int_t imed, Int_t icut)
463{
464// Return cuts icut for medium idmed
465//
466 Int_t jtm = fZlq[fGclink->jtmed-imed];
467//
468// Have the defaults been modified ??
469 Int_t jtmn = fZlq[jtm];
470 if (jtmn >0) {
471 jtm=jtmn;
472
473 } else {
474 jtm=fGclink->jtmed;
475 }
476
477 return Float_t (fZq[jtm+icut]);
478}
479
480TFolder* AliG3toRoot::AddVolume(TObject * obj, TFolder *parent, const char* name)
481{
482// Add item to the list tree
483 TFolder* newFolder = parent->AddFolder(name, "volume");
484 newFolder->Add(obj);
485 return newFolder;
486}
487
488AliG3Volume* AliG3toRoot::Volume(Int_t id)
489
490{
491// Volume at id
492 return (AliG3Volume *) (fVolumes->UncheckedAt(id));
493}
494
495
496void AliG3toRoot::ConvertToRootShapes(TFolder *item, AliNode** node, Int_t nNodes)
497{
498// Convert the geometry represented by TFolders into root shapes
499//
500 AliG3Volume* volume;
501 TArrayF pos;
502 Int_t irot, imat;
503 Int_t npos = 0;
504 Bool_t top=kFALSE;
505
506 char nameV[20];
507 char nameN[20];
508
509 if (!item) {
510 item = fTopFolder;
511 top = kTRUE;
512 }
513 if (nNodes == 0) nNodes = 1;
514
515 TList* folders = (TList*) item->GetListOfFolders();
516 TIter next(folders);
517
518 npos = 0;
519 volume = ((AliG3Volume *) item->FindObject(item->GetName()));
520 Int_t ncopy = volume->NCopies();
521 AliNode** newnode = new AliNode*[(ncopy+1)*nNodes];
522
523 for (Int_t ino=0; ino<nNodes; ino++) {
524
525 pos = volume->Position(0);
526 irot = volume->RotMatrix();
527 imat = volume->Material();
528
529 sprintf(nameV,"v%s%d", volume->GetName(), npos);
530 sprintf(nameN,"%s%d" , volume->GetName(), npos);
531
532
533 imat = volume->Material();
534 Int_t nmat = fMaterials->GetEntriesFast();
535 AliG3Material* mat=0;
536
537 for (Int_t mati=0; mati<nmat; mati++) {
538 mat = (AliG3Material*)
539 (fMaterials->UncheckedAt(mati));
540 if ((mat->Id())==imat) break;
541 }
542
543
544 volume->CreateTShape(nameV, mat);
545
546 if (!top) {
547 node[ino]->cd();
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]);
552 npos++;
553
554 } else {
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");
560 npos++;
561 }
562
563 if (ncopy) {
564 for (Int_t icop = 0; icop < ncopy; icop++) {
565 AliG3Volume* copy = volume->Copy(icop);
566
567 sprintf(nameN,"%s%d" , volume->GetName(), icop+1);
568 if (copy->Posp()) {
569 sprintf(nameV,"v%s%d", volume->GetName(), icop+1);
570 volume->CreateTShape(nameV, mat);
571 }
572 node[ino]->cd();
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]);
579 npos++;
580 } // copy loop
581 } // copies exist
582 } // node loop
583 TObject* obj;
584
585 while ((obj = next()))
586 {
587 if ((AliG3Volume*) obj == volume) continue;
588 item = (TFolder*) obj;
589
590 ConvertToRootShapes(item, newnode, npos);
591 }
592
593// Expand divisions of demand
594 if (fExpand) ExpandDivisions();
595}
596
597void AliG3toRoot::ExpandDivisions(AliNode* node)
598{
599// Expand volume divisions
600//
601
602 Bool_t top = kFALSE;
603
604 if (!node) {
605 node = (AliNode*) fGeometry->GetNode("alice");
606 top = kTRUE;
607 }
608 if (!top && node->Ndiv() > 0 && node->Axis()>0) {
609
610 node->ExpandDivisions();
611 node->GetParent()->RecursiveRemove(node);
612 ExpandDivisions();
613
614 } else {
615 TList* sons = node->GetListOfNodes();
616 TIter next(sons);
617 AliNode* son=0;
618
619 while((son = (AliNode*)next())) {
620 ExpandDivisions(son);
621 }
622 }
623}
624
625
626
627
628
629
630