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