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