EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FairModule.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FairModule.cxx
1 // -------------------------------------------------------------------------
2 // ----- FairModule source file -----
3 // ----- Created 06/01/04 by M. Al-Turany -----
4 // -------------------------------------------------------------------------
5 /* Generated by Together */
6 
7 #include "FairModule.h"
8 
9 
10 #include "FairVolume.h"
11 #include "FairVolumeList.h"
12 #include "FairBaseParSet.h"
13 #include "FairRun.h"
14 
15 #include "FairGeoNode.h"
16 #include "FairRuntimeDb.h"
17 
18 #include "FairGeoInterface.h"
19 #include "FairGeoLoader.h"
20 #include "FairGeoNode.h"
21 #include "FairGeoRootBuilder.h"
22 #include "FairGeoMedia.h"
23 
24 
25 #include "TString.h"
26 #include "TObjArray.h"
27 #include "TGeoVolume.h"
28 #include "TFile.h"
29 #include "TList.h"
30 #include "TKey.h"
31 #include "TGeoManager.h"
32 #include "TGeoVoxelFinder.h"
33 #include "TGeoMatrix.h"
34 
35 
36 #include "TSystem.h"
37 #include <fstream>
38 #include <iostream>
39 
40 
41 TArrayI* FairModule::volNumber=0;
44 TRefArray* FairModule::svList=0;
45 
46 
47 
48 //__________________________________________________________________________
50 {
51  fLogger->Warning(MESSAGE_ORIGIN,"FairModule::ConstructGeometry() : this method has to be implimented in detector class");
52 
53 }
54 //__________________________________________________________________________
56 {
57  fLogger->Debug2(MESSAGE_ORIGIN,"FairModule::ConstructOpGeometry : this method has to be implimented in detector class");
58 
59 }
60 //__________________________________________________________________________
62 {
63 
64 }
65 //__________________________________________________________________________
66 FairModule::FairModule(const char* Name, const char* title ,Bool_t Active)
67  :TNamed(Name, title),
68  fMotherVolumeName(""),
69  fgeoVer("Not defined"),
70  fgeoName("Not defined"),
71  fModId(-1),
72  fActive(Active),
73  fNbOfSensitiveVol(0),
74  fVerboseLevel(0),
75  flGeoPar(0),
76  kGeoSaved(kFALSE),
77  fRootMaterialImportFlag(kFALSE),
78  fLogger(FairLogger::GetLogger())
79 {
80  if(!svList) { svList=new TRefArray(); }
81  if(!vList) { vList=new FairVolumeList(); }
82 
83 }
84 
85 //__________________________________________________________________________
86 
88  : TNamed(),
89  fMotherVolumeName(""),
90  fgeoVer("Not defined"),
91  fgeoName("Not defined"),
92  fModId(-1),
93  fActive(kFALSE),
94  fNbOfSensitiveVol(0),
95  fVerboseLevel(0),
96  flGeoPar(0),
97  kGeoSaved(kFALSE),
98  fRootMaterialImportFlag(kFALSE),
99  fLogger(FairLogger::GetLogger())
100 {
101 
102 }
103 
104 //__________________________________________________________________________
105 void FairModule::Streamer(TBuffer& b)
106 {
107  TNamed::Streamer(b);
108 
109 
110  if (b.IsReading()) {
111  fgeoVer.Streamer(b);
112  fgeoName.Streamer(b);
113  b >> fActive;
114  b >> fModId;
115  } else {
116  fgeoVer.Streamer(b);
117  fgeoName.Streamer(b);
118  b << fActive;
119  b << fModId;
120  }
121 
122 }
123 //__________________________________________________________________________
124 void FairModule::SetGeometryFileName(TString fname, TString geoVer)
125 {
126  fgeoVer=geoVer;
127  TString FileName = fname;
128  TString work = getenv("VMCWORKDIR");
129  TString userwork = getenv("GEOMPATH");
130  if(userwork != "") {
131  fgeoName=userwork;
132  if (!fgeoName.EndsWith("/")) { fgeoName+="/"; }
133  //fgeoName+=fname;
134  if (TString(gSystem->FindFile(fgeoName.Data(),fname)) != TString("")) {
135  fgeoName=fname;
136  fLogger->Info(MESSAGE_ORIGIN, "User path for detector geometry : %s ", fgeoName.Data());
137  } else {
138  fLogger->Warning(MESSAGE_ORIGIN, "Detector geometry was not found in user path : %s ", FileName.Data());
139  fgeoName=work+"/geometry/";
140  fLogger->Info(MESSAGE_ORIGIN, "Try the standard path : %s ",fgeoName.Data());
141  if (TString(gSystem->FindFile(fgeoName.Data(),FileName)) != TString("")) {
142  fgeoName=FileName;
143  fLogger->Info(MESSAGE_ORIGIN, "Reading detector geometry from : %s ", FileName.Data());
144  } else {
145  fLogger->Fatal(MESSAGE_ORIGIN,"Detector geometry not found.");
146  }
147  }
148  } else {
149  fgeoName=work+"/geometry/";
150  fgeoName+=fname;
151  }
152 }
153 //__________________________________________________________________________
154 void FairModule::ProcessNodes(TList* aList)
155 {
156 
157  TListIter iter(aList);
158  FairGeoNode* node = NULL;
159  FairGeoNode* MotherNode =NULL;
160  FairVolume* volume = NULL;
162  FairBaseParSet* par=(FairBaseParSet*)(rtdb->getContainer("FairBaseParSet"));
163  TObjArray* fNodes = par->GetGeoNodes();
164  while( (node = (FairGeoNode*)iter.Next()) ) {
165 
166  node->calcLabTransform();
167  MotherNode=node->getMotherNode();
168  volume = new FairVolume( node->getTruncName(), fNbOfVolumes++);
169  volume->setRealName(node->GetName());
170  vList->addVolume(volume);
171  volume->setGeoNode(node);
172  volume->setCopyNo( node->getCopyNo());
173 
174  if(MotherNode!=0) {
175  volume->setMotherId(node->getMCid());
176  volume->setMotherCopyNo(MotherNode->getCopyNo());
177  }
178  FairGeoVolume* aVol=NULL;
179 
180  if ( node->isSensitive() && fActive ) {
181  volume->setModId(fModId);
182  volume->SetModule(this);
183  svList->Add(volume);
184  aVol = dynamic_cast<FairGeoVolume*> ( node );
185  fNodes->AddLast( aVol );
187  }
188 
189  }
190 }
191 //__________________________________________________________________________
193 {
194 
195  fLogger->Debug2(MESSAGE_ORIGIN, "FairModule::AddSensitiveVolume", v->GetName());
196  // Only register volumes which are not already registered
197  // Otherwise the stepping will be slowed down
198  if( ! vList->findObject(v->GetName() ) ) {
199  FairVolume* volume = NULL;
200  volume = new FairVolume(v->GetName(), fNbOfVolumes++);
201  vList->addVolume(volume);
202  volume->setModId(fModId);
203  volume->SetModule(this);
204  svList->Add(volume);
206  }
207 }
208 
209 
210 //__________________________________________________________________________
212 {
213  FairVolume* fv;
214  FairVolume* fvol=0;
215  for(Int_t i=0; i<vList->getEntries(); i++) {
216  fv=vList->At(i);
217  if((fv->getGeoNode())==fN) {
218  fvol=fv;
219  return fvol;
220  break;
221  }
222  }
223  return fvol;
224 }
225 //__________________________________________________________________________
227 {
236  TGeoManager* OldGeo=gGeoManager;
237  TGeoManager* NewGeo=0;
238  TGeoVolume* volume=0;;
239  TFile* f=new TFile(GetGeometryFileName().Data());
240  TList* l= f->GetListOfKeys();
241  TKey* key;
242  TIter next( l);
243  TGeoNode* n=0;
244  TGeoVolume* v1=0;
245  while ((key = (TKey*)next())) {
246  //std::cout << key->GetClassName() << std::endl;
250  if (strcmp(key->GetClassName(),"TGeoManager") != 0) { continue; }
251  gGeoManager=0;
252  NewGeo = (TGeoManager*)key->ReadObj();
253  break;
254  }
255  if (NewGeo!=0) {
259  NewGeo->cd();
260  volume=(TGeoVolume*)NewGeo->GetNode(0)->GetDaughter(0)->GetVolume();
261  v1=volume->MakeCopyVolume(volume->GetShape());
262  // n=NewGeo->GetTopNode();
263  n=v1->GetNode(0);
264  // NewGeo=0;
265  // delete NewGeo; //move it to the end of the method
266 
267  } else {
272  //key=(TKey*) l->At(0); //Get the first key in the list
273  //volume=dynamic_cast<TGeoVolume*> (key->ReadObj());
274  //if(volume!=0) { n=volume->GetNode(0); }
275  //if(n!=0) { v1=n->GetVolume(); std::cout << n->GetName() << " " << GetName() << std::endl; }
276 
277  //
278  // - AYK, 2013/09/29 -> consider to perform a bit cleaner search (loop
279  // through all keys and request name match); this way may use MC files
280  // to import detector geometry;
281  //
282  TKey* qkey;
283  TIter qnext( l);
284 
285  while ((qkey = (TKey*)qnext())) {
286  volume=dynamic_cast<TGeoVolume*> (qkey->ReadObj());
287  if (!volume) continue;
288 
289  n = volume->GetNode(0);
290  if (!n) continue;
291 
292  // Well, may want to do a better check later (remove "_N" suffix and request
293  // exact match); later;
294  if (TString(n->GetName()).BeginsWith(GetName()))
295  {
296  v1 = n->GetVolume();
297 
298  std::cout << n->GetName() << " " << GetName() << std::endl;
299  break;
300  } //if
301  }
302  }
303 
304  if(v1==0) {
305  fLogger->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31mFairModule::ConstructRootGeometry(): could not find any geometry in File!! \033[0m", GetGeometryFileName().Data());
306  }
307  gGeoManager=OldGeo;
308  gGeoManager->cd();
309  // If AddToVolume is empty add the volume to the top volume Cave
310  // If it is defined check i´f the volume exists and if it exists add the volume from the root file
311  // to the already existing volume
312  TGeoVolume* Cave=NULL;
313  if ( 0 == fMotherVolumeName.Length() ) {
314  Cave= gGeoManager->GetTopVolume(); //printf("%s\n", Cave->GetName()); exit(0);
315  } else {
316  Cave = gGeoManager->GetVolume(fMotherVolumeName); //exit(0);
317  }
318  if(Cave!=NULL) {
320  gGeoManager->AddVolume(v1);
322  TGeoVoxelFinder* voxels = v1->GetVoxels();
323  if (voxels) { voxels->SetNeedRebuild(); }
324 
325  // else { fLogger->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31mFairModule::ConstructRootGeometry(): could not find voxels \033[0m"); }
326 
330  TGeoMatrix* M = n->GetMatrix();
332 
334  gGeoManager->GetListOfMatrices()->Remove(M);
335  TGeoHMatrix* global = gGeoManager->GetHMatrix();
336  gGeoManager->GetListOfMatrices()->Remove(global); //Remove the Identity matrix
338  Cave->AddNode(v1,0, M);
344  ExpandNode(n);
345  if(NewGeo!=0) { delete NewGeo; }
346  delete f;
347  } else {
348  fLogger->Fatal(MESSAGE_ORIGIN,"\033[5m\033[31mFairModule::ConstructRootGeometry(): could not find the given mother volume \033[0m %s \033[5m\033[31m where the geomanger should be added. \033[0m", fMotherVolumeName.Data());
349  }
350 }
351 //__________________________________________________________________________
353 {
354  fLogger->Warning(MESSAGE_ORIGIN,"FairModule::ConstructASCIIGeometry() : this method has to be implimented in detector class");
355 
356 }
357 //__________________________________________________________________________
359 {
360  fLogger->Warning(MESSAGE_ORIGIN,"FairModule::CheckIfSensitive(std::string name): this method has to be implimented in detector class");
361  return kFALSE;
362 }
363 //__________________________________________________________________________
364 
365 void FairModule::ExpandNode(TGeoNode* fN)
366 {
367  TGeoMatrix* Matrix =fN->GetMatrix();
368  if(gGeoManager->GetListOfMatrices()->FindObject(Matrix)) { gGeoManager->GetListOfMatrices()->Remove(Matrix); }
369  TGeoVolume* v1=fN->GetVolume();
370  TObjArray* NodeList=v1->GetNodes();
371  for (Int_t Nod=0; Nod<NodeList->GetEntriesFast(); Nod++) {
372  TGeoNode* fNode =(TGeoNode*)NodeList->At(Nod);
373  TGeoMatrix* M =fNode->GetMatrix();
375 
376  TGeoVolume* v= fNode->GetVolume();
377 
378  // Skip th erest of the loop (including ExpandNode() recursion) once a volume was served once;
379  // NB: this implementation is still not clean since v->RegisterYourself() has a recursion inside
380  // (so daughters will be registered there more than one time, depending on level difference
381  // in the hierarchy); ideally one would call n->GetVolume()->RegisterYourself() in
382  // ConstructRootGeometry() outside of the ExpandNode() call; this way it works, but
383  // simulation itself (for FEMC) becomes few times slower (why?); the implemented trivial
384  // solution speeds up FEMC init phase from ~2 minutes to <1 second and does not affect
385  // simulation time; leave it like this and be happy; eventually may want to arrange
386  // a similar lookup table in AssignMediumAtImport() - see eg eic.patch file in EicRoot
387  // r219 where this stuff is commented out but not removed (media lookup is not really
388  // needed, volume lookup suffices there);
389  if (fGeoVolumeLut.find(v) != fGeoVolumeLut.end()) continue;
390  fGeoVolumeLut.insert(v);
391 
392  if(fNode->GetNdaughters()>0) { ExpandNode(fNode); }
394  if (!gGeoManager->FindVolumeFast(v->GetName())) {
395  fLogger->Debug2(MESSAGE_ORIGIN,"Register Volume : %s ", v->GetName());
396  v->RegisterYourself();
397  }
398  if (CheckIfSensitive(v->GetName())) {
399  fLogger->Debug2(MESSAGE_ORIGIN,"Sensitive Volume : %s ", v->GetName());
401  }
402  }
403 }
404 //__________________________________________________________________________
406 {
407  // Copied from root TGeoMatrix::SetDefaultName() and modified (memory leak)
408  // If no name was supplied in the ctor, the type of transformation is checked.
409  // A letter will be prepended to the name :
410  // t - translation
411  // r - rotation
412  // s - scale
413  // c - combi (translation + rotation)
414  // g - general (tr+rot+scale)
415  // The index of the transformation in gGeoManager list of transformations will
416  // be appended.
417  if (!gGeoManager) { return; }
418  if (strlen(matrix->GetName())) { return; }
419  char type = 'n';
420  if (matrix->IsTranslation()) { type = 't'; }
421  if (matrix->IsRotation()) { type = 'r'; }
422  if (matrix->IsScale()) { type = 's'; }
423  if (matrix->IsCombi()) { type = 'c'; }
424  if (matrix->IsGeneral()) { type = 'g'; }
425  TObjArray* matrices = gGeoManager->GetListOfMatrices();
426  Int_t index = 0;
427  if (matrices) { index =matrices->GetEntriesFast() - 1; }
428  matrix->SetName(Form("%c%i", type, index));
429 }
430 
431 //__________________________________________________________________________
432 
434 {
442 
443  TGeoMedium* med1=v->GetMedium();
444  if(med1 && strcmp(med1->GetName(), "dummy")) {
445  TGeoMaterial* mat1=v->GetMaterial();
446  // FairGeoBuilder does not distinguish material and media names (I guess); STAR
447  // geometry database does (say media CAVE_AIR is done from material AIR); so
448  // switch to using media names here and below;
449 #if _OLD_
450  TGeoMaterial* newMat = gGeoManager->GetMaterial(mat1->GetName());
451 #else
452  TGeoMaterial* newMat = gGeoManager->GetMaterial(med1->GetName());
453 #endif
454  if( newMat==0) {
456 #if _OLD_
457  FairGeoMedium* FairMedium=Media->getMedium(mat1->GetName());
458 #else
459  FairGeoMedium* FairMedium=Media->getMedium(med1->GetName());
460 #endif
461  if (!FairMedium) {
463  // Create medium a la FairRoot by hand; sort of mimic FairGeoMedium::read() call
464  // sequence; this may cause conflicts if more than one ROOT file have material
465  // with the same name; FIXME: if this ever becomes a problem; for now I just need
466  // to import STAR geometry database;
467  FairMedium = new FairGeoMedium(med1->GetName());
468 
469  FairMedium->setNComponents(mat1->GetNelements());
470  //printf("%3d\n", mat1->GetNelements());
471  for(unsigned iq=0; iq<mat1->GetNelements(); iq++) {
472  double a, z, w;
473 
474  mat1->GetElementProp(a, z, w, iq);
475  FairMedium->setComponent(iq, a, z, w);
476  } //for iq
477 
478  FairMedium->setDensity(mat1->GetDensity());
479 
480  // Well, FairGeoMedium::read() also calculates rad.length for pure elements only;
481  if (mat1->GetNelements() == 1) FairMedium->calcRadiationLength();
482 
483  // Parameter order is *ucked up compared to TGeo and parameters renamed ->
484  // carelessly use FairGeoMedium::setMediumPar() sequence;
485  double params[8];
486  for(unsigned iq=0; iq<8; iq++)
487  params[iq] = med1->GetParam(iq);
488  FairMedium->sensFlag = params[0];//=sensFlag;
489  FairMedium->fldFlag = params[1];//=fldFlag;
490  FairMedium->fld = params[2];//=fld;
491  FairMedium->madfld = params[3];//=madfld;
492  FairMedium->maxstep = params[4];//=maxstep;
493  FairMedium->maxde = params[5];//=maxde;
494  FairMedium->epsil = params[6];//=epsil;
495  FairMedium->minstep = params[7];//=minstep;
496 
497  // And do not care about Cerenkov, sorry;
498  }
499  else
500  fLogger->Fatal(MESSAGE_ORIGIN,"Material %s is not defined in ASCII file nor in Root file we Stop creating geometry",
501  mat1->GetName());
502  } //if
503 
504  Int_t nmed=geobuild->createMedium(FairMedium);
505  //FairMedium->print();
506  v->SetMedium(gGeoManager->GetMedium(nmed));
507  gGeoManager->SetAllIndex();
508  } else {
510 #if _OLD_
511  TGeoMedium* med2= gGeoManager->GetMedium(mat1->GetName());
512 #else
513  TGeoMedium* med2= gGeoManager->GetMedium(med1->GetName());
514 #endif
515  v->SetMedium(med2);
516  }
517  } else {
518  if (strcmp(v->ClassName(),"TGeoVolumeAssembly") != 0) {
519  //[R.K.-3.3.08] // When there is NO material defined, set it to avoid conflicts in Geant
520  fLogger->Fatal(MESSAGE_ORIGIN,"The volume %s Has no medium information and not an Assembly so we have to quit", v->GetName());
521  }
522  }
523 }
524 
525 //__________________________________________________________________________
527 
528 
529