]> git.uio.no Git - u/mrichter/AliRoot.git/blob - AliGeant3/AliG3toRoot.cxx
Mostly minor style modifications to be ready for cloning with EMCAL
[u/mrichter/AliRoot.git] / AliGeant3 / AliG3toRoot.cxx
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$
18 Revision 1.3  2002/03/19 09:36:17  morsch
19 Unnecessary includes removes, one included. (Jacek M. Holeczek)
20
21 Revision 1.2  2001/08/30 09:32:30  hristov
22 The operator[] is replaced by At() or AddAt() in case of TObjArray.
23
24 Revision 1.1  2001/07/09 11:43:01  morsch
25 Class 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
45 ClassImp(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 }
72 void 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
95 void 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
317 void 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
389 void 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
411 Int_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
420 Int_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
435 Int_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
454 Int_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
465 Float_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
483 TFolder* 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
491 AliG3Volume* AliG3toRoot::Volume(Int_t id)
492         
493 {
494 // Volume at id
495     return (AliG3Volume *) (fVolumes->UncheckedAt(id));
496 }
497
498
499 void 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
600 void 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