SToGS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
SToGS_DetectorFactory.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 
28 // G4 includes
29 #include "G4Material.hh"
30 #include "G4Box.hh"
31 #include "G4Tubs.hh"
32 #include "G4Polyhedra.hh"
33 #include "G4Sphere.hh"
34 
35 #include "G4LogicalVolume.hh"
36 #include "G4AssemblyVolume.hh"
37 
38 #include "G4PVPlacement.hh"
39 #include "G4PVParameterised.hh"
40 #include "G4UserLimits.hh"
41 #include "G4VisAttributes.hh"
42 #include "G4Colour.hh"
43 #include "G4ios.hh"
44 #include "G4SubtractionSolid.hh"
45 #include "G4PhysicalVolumeStore.hh"
46 #include "G4LogicalVolumeStore.hh"
47 #include "G4SDManager.hh"
48 #include "G4UnitsTable.hh"
49 
50 // Paris includes
51 #include "SToGS_DetectorFactory.hh"
54 
55 #include "G4GDMLParser.hh"
56 
57 using namespace std;
58 using namespace SToGS;
59 
60 // mother of all factories
61 SToGS::DetectorFactory *SToGS::DetectorFactory::pMainFactory = 0x0; DFMessenger *SToGS::DetectorFactory::pMainMessanger = 0x0;
62 //
63 G4int SToGS::DetectorFactory::gCopyNb = 0;
64 
65 // containing the sub factories ...
66 std::vector < SToGS::DetectorFactory * > SToGS::DetectorFactory::fSubFactory;
67 
68 
70 {
71  if ( pMainFactory == 0x0 ) {
72  pMainFactory = new SToGS::DetectorFactory();
73  pMainMessanger = new DFMessenger();
74 
75  SToGS::MaterialConsultant::theConsultant(); // just to be sure SToGS materials are built
76  }
77  return pMainFactory;
78 }
79 
81 {
82  SToGS::DetectorFactory *sub_factory = 0x0;
83 
84  for (std::vector<SToGS::DetectorFactory *>::iterator it = fSubFactory.begin() ; it != fSubFactory.end(); ++it){
85  G4String sub_name = (*it)->GetFactoryName();
86  if ( path.contains(sub_name) ) {
87  sub_factory = (*it);
88  break;
89  }
90  }
91 
92  return sub_factory;
93 }
94 
95 void SToGS::DetectorFactory::ChangeSD(G4String opt, G4VPhysicalVolume *top)
96 {
97  G4VPhysicalVolume *l_top = top;
98  if ( top == 0x0
99  && G4TransportationManager::GetTransportationManager()
100  && G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()) {
101  l_top = G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume();
102  }
103  if ( l_top == 0x0 )
104  return;
105 
106  // collect from top volume all the logical volumes and modify SD accordingly
107  std::vector<G4LogicalVolume *> logical_stored; std::vector<G4VPhysicalVolume *> phycical_stored; std::vector<G4VPhysicalVolume *> phycical_active;
108  //
109  CollectVolumes(l_top, logical_stored, phycical_stored, phycical_active);
110  //
111  for (size_t i = 0; i < logical_stored.size(); i++) {
112 // G4cout << "Changing volume of " << logical_stored[i]->GetName() << G4endl;
113  if ( logical_stored[i]->GetSensitiveDetector() )
114  SetActive(logical_stored[i], opt);
115  }
116 }
117 
118 /*
119 void SToGS::DetectorFactory::ChangeCopyNb(G4VPhysicalVolume *top, G4String which_det, G4int which_nb)
120 {
121  // collect from top volume all the logical volumes and modify SD accordingly
122  std::vector<G4LogicalVolume *> logical_stored; std::vector<G4VPhysicalVolume *> phycical_stored; G4int nb_sd = 0;
123  //
124  CollectVolumes(top, logical_stored, phycical_stored,nb_sd);
125  //
126  for (size_t i = 0; i < phycical_stored.size(); i++) {
127  if ( phycical_stored[i]->GetName() == which_det ) {
128  G4cout << "Changing copy # of " << phycical_stored[i]->GetName() << " to " << which_nb << G4endl;
129  phycical_stored[i]->SetCopyNo(which_nb);
130  }
131  }
132 }
133  */
134 
136 {
137  for (std::vector<SToGS::DetectorFactory *>::iterator it = fSubFactory.begin() ; it != fSubFactory.end(); ++it) {
138  G4cout << "[+..] BUILDING Store " << (*it)->GetFactoryName() << G4endl;
139  (*it)->MakeStore();
140  G4cout << "[..+] BUILDING Store " << (*it)->GetFactoryName() << G4endl;
141  }
142 }
143 
144 void SToGS::DetectorFactory::MakeInStore(G4String name, G4String version_string)
145 {
146  // check if already in store
147  std::ifstream gdml_in(GetFileName(GetDetName(name,version_string), "gdml").data());
148  if ( gdml_in.is_open() ) {
149  gdml_in.close();
150  G4cout << "[===] Detector " << GetDetName(name,version_string) << " already in store " << G4endl;
151  return;
152  }
153  G4cout << "[+..] Building Detector " << GetDetName(name,version_string) << G4endl;
154  G4VPhysicalVolume *theDetector = Make(name, version_string);
155  if (theDetector) {
156  Store(theDetector);
157  }
158  G4cout << "[..+] Building Detector " << GetDetName(name,version_string) << G4endl;
159 }
160 
161 G4String SToGS::DetectorFactory::GetFileName(G4String detname, G4String extention)
162 {
163  G4String result;
164 
165  result = GetFactoryName(); result += detname; result += "."; result += extention;
166  return result;
167 }
168 
169 #include <sstream>
170 
171 void SToGS::DetectorFactory::StreamTouchable(std::ofstream &dmap, G4String dname)
172 {
173  size_t where = dname.find(":");
174  if ( where != std::string::npos ) {
175  std::string tmp = dname.substr( where );
176  dmap << " " << tmp;
177  }
178 }
179 
180 void SToGS::DetectorFactory::StoreMap(std::ofstream &amap,
181  std::ofstream &dmap,
182  std::vector<G4LogicalVolume *> &logical_stored,
183  std::vector<G4VPhysicalVolume *> &physical_stored, std::vector<G4VPhysicalVolume *> &physical_active,
184  G4VPhysicalVolume *theDetector)
185 {
186  G4LogicalVolume *alogical = theDetector->GetLogicalVolume(); G4VPhysicalVolume *aphysical = 0x0;
187  if ( alogical == 0x0 )
188  return;
189 
190  // check first if logical already in the list --> means already written in the amap file
191  G4bool in_the_list = false;
192  for (size_t i = 0; i < logical_stored.size() ; i++) {
193  if (alogical == logical_stored[i] )
194  in_the_list = true;
195  }
196  if ( !in_the_list ) {
197 
198  G4String sd("S ");
199 
200  if ( alogical->GetSensitiveDetector() ) {
201  sd += (alogical->GetSensitiveDetector())->GetFullPathName();
202  }
203  else
204  sd += "-";
205 
206  const G4VisAttributes *att = alogical->GetVisAttributes(); G4Color color(0.8,0.8,0.8,0);
207  if ( att )
208  color = att->GetColor();
209 
210  amap << alogical->GetName()
211  << "\t"
212  << "C "
213  << setprecision(2)
214  << color.GetRed()
215  << " "
216  << color.GetGreen()
217  << " "
218  << color.GetBlue()
219  << " "
220  << color.GetAlpha()
221  << "\t"
222  << sd
223  << " F -"
224  << endl;
225 
226  logical_stored.push_back(alogical);
227  }
228 
229  // add this to the physical store ... requires to get the rotation in world ...
230  // no need to check if alread there ad it is removed at the end of the method
231  physical_stored.push_back(theDetector);
232 
233  // keep in the first slot the first physical detector in a tree structure that are not the world ... just in case
234  G4int is_to_be_removed_from_active = false;
235  if ( theDetector->GetMotherLogical() && physical_active.size() == 0 ) {
236  physical_active.push_back(theDetector);
237  is_to_be_removed_from_active = true;
238  }
239  // if an active detector, keep the global unique id, the touchable history and global translation
240  if ( theDetector->GetLogicalVolume()->GetSensitiveDetector() ) {
241 
242  if ( is_to_be_removed_from_active == false ) { // not added by conditions first top volume but not world
243  physical_active.push_back(theDetector);
244  is_to_be_removed_from_active = true;
245  }
246 
247  // add this detector to the list so that one can keep a history of physical to reach a sensitive volume
248  G4int offset = 0, global_unique_copy_number = 0;
249  G4String first_physical = physical_active[0]->GetName();
250  //
251  for (size_t i = 0; i < physical_active.size() ; i++) {
252  // touchable += physical_active[i]->GetName();
253  if ( i == 0 ) {
254  offset = physical_active[i]->GetCopyNo();
255  }
256  }
257  // if depth is reduced to one, otherwise unqiue number is deduced by adding top copy number with this copy number
258  if ( physical_active.size() > 1 ) {
259  global_unique_copy_number = offset + theDetector->GetCopyNo();
260  }
261  else
262  global_unique_copy_number = theDetector->GetCopyNo();
263 
264  G4ThreeVector ToTr;
265  for (size_t i = 0; i < physical_stored.size() ; i++) {
266  ToTr += physical_stored[i]->GetTranslation();
267  }
268  dmap << setw(5) << setfill('0') << global_unique_copy_number << "\t"
269  << physical_active[0]->GetName() << "\t" << physical_active[0]->GetCopyNo() << "\t"
270  << theDetector->GetName() << "\t" << theDetector->GetCopyNo() << "\t" ;
271 
272  //<< theDetector->GetName() << "\t";
273  // StreamTouchable(dmap, theDetector->GetName()); dmap << "\t";
274  // dmap << theDetector->GetName() << "\t";
275  // dmap << touchable << "\t";
276 
277  if ( ToTr.getX() < 0.0 )
278  dmap << ToTr.getX()/CLHEP::cm << " ";
279  else
280  dmap << "+" << ToTr.getX()/CLHEP::cm << " ";
281 
282  if ( ToTr.getY() < 0.0 )
283  dmap << ToTr.getY()/CLHEP::cm << " ";
284  else
285  dmap << "+" << ToTr.getY()/CLHEP::cm << " ";
286 
287  if ( ToTr.getZ() < 0.0 )
288  dmap << ToTr.getZ()/CLHEP::cm << " ";
289  else
290  dmap << "+" << ToTr.getZ()/CLHEP::cm << " ";
291 
292  dmap << " cm\t";
293  dmap << " "<< std::endl;
294 
295  /*
296  dmap << setw(5) << setfill('0')
297  << theDetector->GetCopyNo() << "\t"
298  << theDetector->GetName() << "\t";
299  StreamTouchable(dmap, theDetector->GetName()); dmap << "\t";
300  // dmap << theDetector->GetName() << "\t";
301 
302  if ( theDetector->GetTranslation().getX() < 0.0 )
303  dmap << theDetector->GetTranslation().getX()/CLHEP::cm << " ";
304  else
305  dmap << "+" << theDetector->GetTranslation().getX()/CLHEP::cm << " ";
306 
307  if ( theDetector->GetTranslation().getY() < 0.0 )
308  dmap << theDetector->GetTranslation().getY()/CLHEP::cm << " ";
309  else
310  dmap << "+" << theDetector->GetTranslation().getY()/CLHEP::cm << " ";
311 
312  if ( theDetector->GetTranslation().getZ() < 0.0 )
313  dmap << theDetector->GetTranslation().getZ()/CLHEP::cm << " ";
314  else
315  dmap << "+" << theDetector->GetTranslation().getZ()/CLHEP::cm << " ";
316 
317  dmap << " cm\t";
318  dmap << " "<< std::endl;
319  */
320  //
321  }
322 
323  for (G4int i = 0; i < alogical->GetNoDaughters(); i++) {
324  aphysical = alogical->GetDaughter(i);
325  StoreMap(amap, dmap, logical_stored, physical_stored, physical_active, aphysical /*, theDetector->GetName() */);
326  }
327  // remove it to the history list
328  physical_stored.pop_back();
329  if ( is_to_be_removed_from_active ) {
330  physical_active.pop_back();
331  }
332 }
333 
334 void SToGS::DetectorFactory::CollectVolumes(G4VPhysicalVolume *theDetector,
335  std::vector<G4LogicalVolume *> &logical_stored,
336  std::vector<G4VPhysicalVolume *> &phycical_stored, std::vector<G4VPhysicalVolume *> &physical_active)
337 {
338  G4LogicalVolume *alogical = theDetector->GetLogicalVolume(); G4VPhysicalVolume *aphysical = 0x0; G4bool in_the_list;
339 
340  in_the_list = false;
341  for (size_t i = 0; i < phycical_stored.size() ; i++) {
342  if ( aphysical == phycical_stored[i] ) {
343  in_the_list = true;
344  break;
345  }
346  }
347  if ( !in_the_list ) { // add this to the list if not yet there
348  phycical_stored.push_back(theDetector);
349  if ( theDetector->GetLogicalVolume()->GetSensitiveDetector() ) {
350  physical_active.push_back(theDetector);
351  }
352  }
353  in_the_list = false;
354  for (size_t i = 0; i < logical_stored.size() ; i++) {
355  if ( alogical == logical_stored[i] ) {
356  in_the_list = true;
357  break;
358  }
359  }
360  if ( !in_the_list ) {
361  logical_stored.push_back(alogical);
362  }
363 
364  // recursive call
365  for (G4int i = 0; i < alogical->GetNoDaughters(); i++) {
366  aphysical = alogical->GetDaughter(i);
367  CollectVolumes(aphysical,logical_stored, phycical_stored, physical_active);
368  }
369 }
370 
371 #include <sstream>
372 
373 void SToGS::DetectorFactory::Store(G4VPhysicalVolume *theDetector)
374 {
375  G4String filename = GetFileName(theDetector->GetName(), "gdml");
376 
377  std::ifstream gdml_in(filename.data());
378  if ( gdml_in.is_open() ) {
379  gdml_in.close();
380  G4cout << " file already exiting " << filename.data() << G4endl;
381  return;
382  }
383  else {
384  // store geometry in gdml
385  G4GDMLParser parser;
386  parser.Write(filename.data(),theDetector,false);
387  }
388 
389  // store attribute
390  filename = GetFileName(theDetector->GetName(), "amap"); std::ofstream amap(filename.data());
391  filename = GetFileName(theDetector->GetName(), "dmap"); std::ofstream dmap(filename.data());
392 
393  if ( amap.is_open() && dmap.is_open() ) {
394 
395  std::vector<G4LogicalVolume *> logical_stored; std::vector<G4VPhysicalVolume *> physical_stored, physical_active;
396 
397  for (G4int i = 0; i < theDetector->GetLogicalVolume()->GetNoDaughters(); i++) {
398  StoreMap(amap, dmap, logical_stored, physical_stored, physical_active, theDetector->GetLogicalVolume()->GetDaughter(i) );
399  }
400  }
401 }
402 
403 G4String SToGS::DetectorFactory::GetDetName(const G4String &path) const
404 {
405  G4String tmp = path;
406 
407  // replace slashes by space
408  G4int start = path.last('/');
409  tmp.remove(0,start+1);
410  start = tmp.last('.');
411  tmp.remove(start);
412 
413  return tmp;
414 }
415 
416 G4String SToGS::DetectorFactory::GetDetName(G4String name, G4String version_string) const
417 {
418  G4String detname = name;
419 
420  if ( version_string != "" ) {
421  detname += "_";
422  detname += version_string;
423  }
424 
425  return detname;
426 }
427 
428 void SToGS::DetectorFactory::AssemblyRename(G4AssemblyVolume *assembly, const G4String &volume_to_find) const
429 {
430  std::string tmp;
431 
432  std::vector < G4VPhysicalVolume* >::iterator vol = assembly->GetVolumesIterator();
433  for (size_t i = 0; i < assembly->TotalImprintedVolumes(); i++) {
434  G4VPhysicalVolume *an_element = *vol++;
435 
436  tmp = (an_element)->GetName();
437  if ( tmp.find(volume_to_find) != std::string::npos ) { // ok, rename volume
438  //
439  G4int av, impr, pv, nbread; char *tmpname = new char[tmp.size()];
440 
441  // necessary otherwise sscanf does not work and set string up to the end
442  tmp.replace(tmp.find("_pv"), 3, std::string(" _pv"));
443  nbread = sscanf(tmp.data(),"av_%d_impr_%d_%s _pv_%d",&av,&impr,tmpname,&pv);
444  if ( nbread == 4 ) {
445  G4cout << " Volume " << (an_element)->GetName() << ", with copy number " << an_element->GetCopyNo() << " " << (void*)(an_element->GetLogicalVolume()) << G4endl;;
446  sprintf(tmpname,"%s_%d",tmpname,--impr);
447  (an_element)->SetName(tmpname);
448  G4cout << " |--> becomes " << (an_element)->GetName() << G4endl;
449  }
450  delete [] tmpname;
451  }
452  }
453 }
454 
455 G4int SToGS::DetectorFactory::DoMap(G4AssemblyVolume *assembly,
456  G4VPhysicalVolume *volume_used_to_built_assembly, G4int copy_number_offset) const
457 {
458 
459  G4cout << "[+] Results of snapshots of " << volume_used_to_built_assembly->GetName() << endl;
460 
461  std::string tmp; // std::vector <G4int> items; // for each imprinted volumes, current number
462 
463  // from the detector used to make the assembly, collect logical and physical to remap the imprinted volumes
464  std::vector<G4LogicalVolume *> logical_stored; std::vector<G4VPhysicalVolume *> physical_stored; std::vector<G4VPhysicalVolume *> physical_active;
465  //
466  CollectVolumes(volume_used_to_built_assembly, logical_stored, physical_stored, physical_active);
467  //
468  std::vector<G4int > volume_counter; volume_counter.resize(physical_stored.size(),0);
469  // items.resize( assembly->GetImprintsCount() , 0 );
470 
471  // now loop on the imprinted volumes and modify the mapping i.e. the name of the imprinted volumes and the copy number of sensitives
472  std::vector < G4VPhysicalVolume* >::iterator vol = assembly->GetVolumesIterator();
473  for (size_t i = 0; i < assembly->TotalImprintedVolumes(); i++) {
474 
475  G4VPhysicalVolume *an_element = *vol++;
476  tmp = (an_element)->GetName();
477 
478  // necessary otherwise sscanf does not work and set string up to the end
479  G4int av, impr, pv, nbread; char *tmpname = new char[tmp.size()];
480  tmp.replace(tmp.find("_pv"), 3, std::string(" _pv"));
481  nbread = sscanf(tmp.data(),"av_%d_impr_%d_%s _pv_%d",&av,&impr,tmpname,&pv);
482  //
483  impr--;
484 
485  // look for the physical volume this imprinted volumes refered to, extract the name and add :impr
486  G4int keep_j = 0;
487  for (size_t j = 1; j < physical_stored.size(); j++) {
488  if ( an_element->GetLogicalVolume() == physical_stored[j]->GetLogicalVolume() ) {
489  if ( impr == volume_counter[j] ) {
490  keep_j = j;
491  volume_counter[j]++;
492  break;
493  }
494  }
495  }
496  //
497  ostringstream hname;
498  hname << volume_used_to_built_assembly->GetName() << ":" << setw(3) << setfill('0') << impr << ":" << physical_stored[keep_j]->GetName() ;
499  if ( physical_stored[keep_j]->GetLogicalVolume()->GetNoDaughters() == 0 ) {
500  if ( physical_stored[keep_j]->GetLogicalVolume()->GetSensitiveDetector() ) {
501  (an_element)->SetName(hname.str());
502  (an_element)->SetCopyNo( copy_number_offset + impr*physical_active.size() + physical_stored[keep_j]->GetCopyNo() );
503  G4cout << " Set Copy Number of Imprinted Physical Volume " << (an_element)->GetName() << " to " << (an_element)->GetCopyNo() << G4endl;
504  }
505  else {
506  (an_element)->SetName(hname.str());
507  (an_element)->SetCopyNo( physical_stored[keep_j]->GetCopyNo() );
508  G4cout << " Set Copy Number of Imprinted Physical Volume " << (an_element)->GetName() << " to " << (an_element)->GetCopyNo() << G4endl;
509  }
510  }
511  else {
512  (an_element)->SetName(hname.str());
513  (an_element)->SetCopyNo( copy_number_offset + impr*physical_active.size() );
514  G4cout << " Set Copy Number of Imprinted Physical Volume " << (an_element)->GetName() << " to " << (an_element)->GetCopyNo() << G4endl;
515  }
516  //
517  delete [] tmpname;
518  }
519 
520  G4cout << "[-] Results of snapshots of " << volume_used_to_built_assembly->GetName() << endl;
521 
522  return physical_active.size();
523 }
524 
525 void SToGS::DetectorFactory::SetActive(G4LogicalVolume *pv, const G4String &opt)
526 {
527  //
528  std::string lopt = opt, tmp; G4bool ok = false;
529 // if ( lopt.find('^') == std::string::npos ) { // only one string, force to finish it with separtor ^
530  // lopt += "^";
531  // }
532  lopt += "^";
533 
534  std::vector < std::string > all_opt; std::vector < size_t > pos; size_t start = 0;
535  //
536  for (size_t i = 0; i < lopt.size(); i++) { // search for one sequence i.e a string stopped by ^
537 
538  if ( lopt[i] == '^' ) {
539 
540  tmp = lopt.substr(start,i-start); start = i+1;
541 
542  pos.clear();
543  for (size_t j = 0; j < tmp.size(); j++) { // check the sequence contains 3 times the character |
544  if ( tmp[j] == '|' ) {
545  pos.push_back ( j );
546  }
547  }
548  if ( pos.size() == 2 ) {
549  tmp += "|";
550  pos.push_back( tmp.size() - 1 ); // in case color is not defined just set pos[2] to end of string
551  }
552  if ( pos.size() == 3 ) { // valid expression
553 
554  G4String volumename = tmp.substr(0,pos[0]);
555  G4String matname = tmp.substr(pos[0]+1,pos[1]-pos[0]-1);
556  G4String sdname = tmp.substr(pos[1]+1,pos[2]-pos[1]-1);
557  G4String color = tmp.substr(pos[2]+1);
558 
559  // G4cout << " dec (" << tmp << ") " << volumename << " " << matname << " " << sdname << " " << color << G4endl;
560  // G4cout << " from " << pv->GetName() << " " << pv->GetLogicalVolume()->GetMaterial()->GetName() << G4endl;
561 
562  G4int nb_ok = 0;
563  // compare volume name, matname,
564  if ( volumename.find("*") == std::string::npos ) { // a given type of volume
565  if ( pv->GetName().find(volumename) != std::string::npos )
566  nb_ok++;
567  }
568  else nb_ok++;
569 
570  if ( matname.find("*") == std::string::npos ) {// a given type of material
571  if ( pv->GetMaterial()->GetName().find(matname) != std::string::npos )
572  nb_ok++;
573  }
574  else nb_ok++;
575  // decode color. if not given set to default only if color not yet defined
576  G4VisAttributes *visatt = 0x0; G4int valid_col = 0; G4double r = 0.5, g = 0.5, b = 0.5, a = 0.5;
577  for (size_t k = 0; k < color.size(); k++) {
578  if ( color[k] == ';' ) {
579  valid_col++;
580  color[k] = ' ';
581  }
582  }
583  if ( valid_col == 3 ) {
584  istringstream col(color);
585  col >> r >> g >> b >> a;
586 
587  visatt = new G4VisAttributes( G4Colour(r, g, b, a) );
588  pv->SetVisAttributes( visatt );
589  }
590  if ( pv->GetSensitiveDetector() == 0x0 ) {
591  visatt = new G4VisAttributes( G4Colour(r, g, b, a) );
592  pv->SetVisAttributes( visatt );
593  }
594 
595  // check sensitivity. extention list of name separted by ; for scorer ?
596  G4VSensitiveDetector *sensdet = GetSD(sdname);
597 
598  if ( nb_ok == 2 ) { // should be added to the list of sensitive detectors.
599  if ( sensdet ) {
600  // if ( G4SDManager::GetSDMpointer()->FindSensitiveDetector(sdname) ) {
601  ok = true;
602  }
603  }
604  if ( ok ) {
605  pv->SetSensitiveDetector(sensdet);
606  G4cout << pv->GetName() << " is now sensitive of type " << sensdet->GetFullPathName() << G4endl;
607  }
608  if ( ok )
609  break;
610  }
611  }
612  }
613 }
614 
615 G4VSensitiveDetector *SToGS::DetectorFactory::GetSD(G4String sdname, const char sd_type)
616 {
617  G4VSensitiveDetector *sensdet = 0x0;
618 
619  // test first if found in SDManager
620  sensdet = G4SDManager::GetSDMpointer()->FindSensitiveDetector(sdname,false);
621  if ( sensdet == 0x0 ) {
622  if ( sd_type == 'S' ) {
623  if ( sdname == "/SToGS/SD/CopCluster")
625  if ( sdname == "/SToGS/SD/Tracker")
627  }
628  if ( sd_type == 's' ) {
629  }
630 
631  if (sensdet) {
632  G4cout << "[i] " << sensdet->GetFullPathName() << " has been added to the list of SD detector" << G4endl;
633  }
634  }
635  return sensdet;
636 }
637 
638 G4VPhysicalVolume *SToGS::DetectorFactory::Import(G4String gdmlfile, G4String detname, const G4String &opt_amap, const G4String &opt_dmap)
639 {
640  G4VPhysicalVolume *theDetector = 0x0; // G4String detname, fullname;
641 
642  // check if file exist
643  std::ifstream isgdml_in(gdmlfile.data());
644  if ( isgdml_in.is_open() ) {
645  isgdml_in.close();
646  }
647  else {
648  return theDetector;
649  }
650 
651  cout << "[+..] Importing " << gdmlfile << " in " << GetFactoryName() << detname << endl;
652 
653  G4GDMLParser parser;
654  parser.Read(gdmlfile,false);
655 
656  theDetector = parser.GetWorldVolume();
657  if ( theDetector ) {
658 
659  // change top names
660  theDetector->SetName(detname);
661  theDetector->GetLogicalVolume()->SetName(detname);
662 
663  // collect logical to eventual set sensitivity using opt
664  std::vector<G4LogicalVolume *> logical_stored; std::vector<G4VPhysicalVolume *> phycical_stored; std::vector<G4VPhysicalVolume *> phycical_active;
665  //
666  CollectVolumes(theDetector, logical_stored, phycical_stored, phycical_active);
667 
668  for (size_t i = 0; i < logical_stored.size(); i++) {
669  SetActive(logical_stored[i], opt_amap);
670  }
671  for (size_t i = 0; i < phycical_stored.size(); i++) {
672 
673  if ( phycical_stored[i]->GetLogicalVolume()->GetSensitiveDetector() ) {
674  phycical_stored[i]->SetCopyNo( SToGS::DetectorFactory::AddGCopyNb() );
675  }
676  else
677  phycical_stored[i]->SetCopyNo(-1);
678  //
679  if ( opt_dmap == "T" && phycical_stored[i] != theDetector && phycical_stored[i]->GetCopyNo() >=0 ) {
680  ostringstream tmp;
681  tmp << phycical_stored[i]->GetName() << ":" << phycical_stored[i]->GetCopyNo();
682 
683  phycical_stored[i]->SetName(tmp.str());
684  }
685  }
686  Store(theDetector);
687  }
688  cout << "[..+] Importing " << gdmlfile << " in store " << GetFactoryName() << " with name " << detname << endl;
689 
690  return theDetector;
691 }
692 
693 G4VPhysicalVolume *SToGS::DetectorFactory::Get(G4String basename)
694 {
695  G4VPhysicalVolume *theDetector = 0x0; G4String detname, fullname;
696 
697  fullname = basename;
698  fullname += ".gdml";
699 
700  // check is already loaded
701  for (size_t i = 0; i < fLoadedPhysical.size(); i++) {
702  if ( fLoadedPhysical[i].first == fullname ) {
703  theDetector = fLoadedPhysical[i].second;
704  break;
705  }
706  }
707  if ( theDetector ) {
708  return theDetector;
709  }
710 
711  // get it for the first time: load and apply amp, dmap if asked
712  std::ifstream isgdml_in(fullname.data());
713  if ( isgdml_in.is_open() ) {
714  isgdml_in.close();
715  }
716  else {
717  return theDetector;
718  }
719 
720  cout << "[+..] Loading from store " << basename << endl;
721 
722  G4GDMLParser parser;
723  parser.Read(fullname,false);
724  //
725  detname = GetDetName(fullname); theDetector = parser.GetWorldVolume(detname); // load geometry from gdml
726  if ( theDetector == 0x0 ) {
727  // should add a warning
728  return theDetector;
729  }
730 
731  std::pair < G4String, G4VPhysicalVolume *> p(fullname,theDetector); // add the new loaded detector to the list
732  fLoadedPhysical.push_back(p);
733 
734  // just remove _PV added by G4
735  G4String phy_name = theDetector->GetName();
736  size_t pos = phy_name.find("_PV");
737  phy_name.erase(pos,3);
738  // phy_name += ":0";
739  theDetector->SetName(phy_name);
740 
741  GetAttributes(basename, true, true);
742 
743  G4cout << "[..+] Loading from store " << basename << G4endl;
744 
745  return theDetector;
746 }
747 
748 void SToGS::DetectorFactory::GetAttributes(G4String basename, G4bool do_amap, G4bool do_dmap)
749 {
750  G4VPhysicalVolume *theDetector; G4String detname, fullname;
751 
752  theDetector = Get(basename);
753  if ( theDetector == 0x0 )
754  return;
755 
756  if ( do_amap == false && do_amap == false ) { // no need to proceed
757  return;
758  }
759 
760  G4cout << "[+..] Loading Attributes from store " << basename << endl;
761 
762  // now apply map
763  fullname = basename; fullname += ".dmap"; std::ifstream dmap(fullname.data());
764  fullname = basename; fullname += ".amap"; std::ifstream amap(fullname.data());
765 
766  std::vector<G4LogicalVolume *> logical_stored; std::vector<G4VPhysicalVolume *> phycical_stored; std::vector<G4VPhysicalVolume *> physical_active;
767  G4String aline; G4bool has_done_amap = false;
768  //
769  CollectVolumes(theDetector, logical_stored, phycical_stored, physical_active);
770  //
771 
772  if ( do_amap ) {
773  if ( amap.is_open() ) {
774  // logicals
775  getline(amap,aline);
776  while ( amap.good() && !amap.eof() ) {
777 
778  istringstream decode(aline);
779  G4String vname, key_sd, sd, key_color, touchable; G4double r,g,b,a;
780 
781  decode >> vname
782  >> key_color
783  >> r
784  >> g
785  >> b
786  >> a
787  >> key_sd
788  >> sd
789  ;
790 
791  for (size_t i = 0; i < logical_stored.size(); i++) {
792  if ( vname == logical_stored[i]->GetName() ) {
793  //G4cout << " Change attributes [colors] of " << vname << " to " << G4Color(r,g,b,a) << G4endl;
794  //
795  G4VisAttributes visatt(G4Color(r,g,b,a));
796  if ( key_color == "C" )
797  visatt.SetVisibility(true);
798  else
799  visatt.SetVisibility(false);
800 
801  logical_stored[i]->SetVisAttributes(visatt);
802 
803  // SD
804  if ( sd != "-" ) { // means a sensitive detector so look for it and assign to the volume
805  G4VSensitiveDetector * sensdet = GetSD(sd);
806  if (sensdet) {
807  // G4cout << " Change attribute [sensitive] of " << vname << " to " << sd << G4endl;
808  logical_stored[i]->SetSensitiveDetector(sensdet);
809  }
810  }
811  // others ... field etc ...
812 
813  break;
814  }
815  }
816  aline = "";
817  getline(amap,aline);
818  }
819  }
820  else { // do an amap file with all the sensitive detectors
821  fullname = basename; fullname += ".amap"; std::ofstream amap_(fullname.data());
822 
823  if ( amap_.is_open() ) {
824  has_done_amap = true;
825  for (size_t i = 0; i < logical_stored.size(); i++) {
826 
827  //TODO take into account SD in case of import of pure GDML file into factory
828  // if ( logical_stored[i] == theDetector->GetLogicalVolume() ) { // mother is not a
829  // continue;
830  // }
831 
832  amap_ << logical_stored[i]->GetName()
833  << "\t"
834  << "C "
835  << setprecision(2)
836  << "0.5"
837  << " "
838  << "0.5"
839  << " "
840  << "0.5"
841  << " "
842  << "0.5"
843  << "\t"
844  << " S -"
845  << " F -"
846  << endl;
847  }
848  }
849  }
850 
851  }
852  //
853  if ( do_dmap ) {
854  if ( dmap.is_open() ) {
855 
856  for (size_t i = 0; i < phycical_stored.size(); i++) {
857  phycical_stored[i]->SetCopyNo(-1);
858  }
859 
860  // physicals
861  getline(dmap,aline);
862  while ( dmap.good() && !dmap.eof()) {
863 
864  G4String pname, unit, firstpname; G4double x,y,z; G4int uid, top_id, id;
865  istringstream decode(aline);
866 
867  decode >> uid
868  >> firstpname
869  >> top_id
870  >> pname
871  >> id
872  >> x
873  >> y
874  >> z
875  >> unit
876  ;
877 
878  // cout << " Change Copy number of " << pname << phycical_stored.size() << endl;
879  G4cout << " Load Copy number of " << firstpname << " [" << top_id << "] and " << pname << " [" << id << "] " << G4endl;
880 
881  // std::vector<G4bool> is_changed(phycical_stored.size(),0); // to avoid applying modification more that once
882  for (size_t i = 0; i < phycical_stored.size(); i++) {
883  if ( firstpname == phycical_stored[i]->GetName() ) {
884  // G4cout << " Load Copy number of " << firstpname << " [" << top_id << "] " << G4endl;
885  //
886  phycical_stored[i]->SetCopyNo(top_id);
887  }
888  if ( pname == phycical_stored[i]->GetName() ) {
889  // G4cout << " Load Copy number of " << pname << " [" << id << "] " << G4endl;
890  //
891  phycical_stored[i]->SetCopyNo(id);
892  }
893  }
894  //
895  aline = "";
896  getline(dmap,aline);
897  }
898  //SToGS::DetectorFactory::SetGCopyNb( SToGS::DetectorFactory::GetGCopyNb() + max_uid );
899  // in principle consecutive copy numbers ... but just in case take the highest found ...
900  }
901  else {
902  for (size_t i = 0; i < phycical_stored.size(); i++) {
903  phycical_stored[i]->SetCopyNo(-1);
904  }
905 
906  if ( !has_done_amap ) { // already an amap, change copy # of active volumes and store results in dmap
907 
908  fullname = basename; fullname += ".dmap"; std::ofstream dmap_(fullname.data());
909 
910  for (size_t i = 0; i < phycical_stored.size(); i++) {
911  if ( phycical_stored[i]->GetLogicalVolume()->GetSensitiveDetector() ) {
912  cout << " Change Name and Copy number of "
913  << phycical_stored[i]->GetName() << " -> "
914  << phycical_stored[i]->GetName() << ": " << SToGS::DetectorFactory::GetGCopyNb() << " "
916  //
917  ostringstream tmp; tmp << phycical_stored[i]->GetName(); tmp << ":"; tmp << SToGS::DetectorFactory::GetGCopyNb();
918 
919  phycical_stored[i]->SetName(tmp.str());
920  phycical_stored[i]->SetCopyNo( SToGS::DetectorFactory::AddGCopyNb() );
921 
922  if ( dmap_.is_open() ) {
923  dmap_ << setw(5) << setfill('0')
924  << phycical_stored[i]->GetCopyNo() << "\t"
925  << phycical_stored[i]->GetName() << "\t";
926  StreamTouchable(dmap_, phycical_stored[i]->GetName()); dmap_ << "\t";
927 
928  if ( phycical_stored[i]->GetTranslation().getX() < 0.0 )
929  dmap_ << phycical_stored[i]->GetTranslation().getX()/CLHEP::cm << " ";
930  else
931  dmap_ << "+" << phycical_stored[i]->GetTranslation().getX()/CLHEP::cm << " ";
932 
933  if ( phycical_stored[i]->GetTranslation().getY() < 0.0 )
934  dmap_ << phycical_stored[i]->GetTranslation().getY()/CLHEP::cm << " ";
935  else
936  dmap_ << "+" << phycical_stored[i]->GetTranslation().getY()/CLHEP::cm << " ";
937 
938  if ( phycical_stored[i]->GetTranslation().getZ() < 0.0 )
939  dmap_ << phycical_stored[i]->GetTranslation().getZ()/CLHEP::cm << " ";
940  else
941  dmap_ << "+" << phycical_stored[i]->GetTranslation().getZ()/CLHEP::cm << " ";
942 
943  dmap_ << " cm\t";
944  dmap_ << " "<< std::endl;
945  }
946  }
947  }
948  }
949  }
950  }
951  cout << "[..+] Loading Attributes from store " << basename << endl;
952 }
953 
954 
955 G4int SToGS::DetectorFactory::ReMap(G4VPhysicalVolume *adetector, G4int offset)
956 {
957  std::vector<G4LogicalVolume *> logical_stored; std::vector<G4VPhysicalVolume *> physical_stored, physical_active;
958  CollectVolumes(adetector, logical_stored, physical_stored, physical_active);
959 
960  for (size_t i = 0; i < physical_active.size(); i++) {
961  G4cout << "---> Changing Copy Number of Detector " << physical_active[i]->GetName() << " from " << physical_active[i]->GetCopyNo()
962  << " to " << offset + i << G4endl;;
963  physical_active[i]->SetCopyNo(offset + i);
964  }
965  return G4int(physical_active.size());
966 }
967 
968 G4int SToGS::DetectorFactory::Set(G4String basename, G4VPhysicalVolume *mother,
969  G4int top_copy_number_offset, const G4ThreeVector *T, const G4RotationMatrix *R, G4int imprint_number)
970 {
971  G4VPhysicalVolume *thefullDetector = 0x0, *subdetector ; G4LogicalVolume *volume_to_copy;
972 
973  // load from factory the detector, remove the envelop and move the content into mother with all its attribute
974  thefullDetector = Get(basename);
975  if ( thefullDetector == 0x0 ) {
976  return -1;
977  }
978  else { volume_to_copy = thefullDetector->GetLogicalVolume(); }
979 
980  // to count the number of active volumes
981  std::vector<G4LogicalVolume *> logical_stored; std::vector<G4VPhysicalVolume *> phycical_stored; std::vector<G4VPhysicalVolume *> phycical_active;
982  //
983  CollectVolumes(thefullDetector, logical_stored, phycical_stored, phycical_active);
984 
985  // to place new volumes with correct top number
986  for (G4int i = 0; i < volume_to_copy->GetNoDaughters(); i++) {
987 
988  // new sub-detector
989  subdetector = volume_to_copy->GetDaughter(i);
990 
991  // get postion of this sub-detector with repect to its mother and combines with the new position
992  /*
993  G4ThreeVector *T_ = new G4ThreeVector(); G4RotationMatrix *R_ = new G4RotationMatrix();
994  //
995  (*T_) = subdetector->GetObjectTranslation();
996  if ( subdetector->GetRotation() ) {
997  (*R_) = (*subdetector->GetRotation());
998  }
999  if ( T )
1000  (*T_) += (*T);
1001  if ( R )
1002  (*R_) = (*R) * (*R_);
1003  */
1004 
1005 
1006  // just a limitation ... to see how to deal with assemblemy, replica ...
1007  if ( dynamic_cast<G4PVPlacement *>(subdetector) == 0x0 ) {
1008  G4cout << " Current limitation in setting this kind of physical volume " << subdetector->GetName() << G4endl;
1009  continue;
1010  }
1011 
1012  // this is a top volume without daugther ... take the current copy number and add offset
1013  ostringstream hname;
1014  hname << thefullDetector->GetName() << ":" << setw(3) << setfill('0') << imprint_number << ":" << subdetector->GetName() ;
1015 
1016  /*
1017  if ( subdetector->GetLogicalVolume()->GetNoDaughters() == 0 ) {
1018  if ( subdetector->GetLogicalVolume()->GetSensitiveDetector() ) {
1019  new G4PVPlacement(R_,(*T_),
1020  subdetector->GetLogicalVolume(),
1021  hname.str(),
1022  mother->GetLogicalVolume(),
1023  false,
1024  top_copy_number_offset + subdetector->GetCopyNo() );
1025  G4cout << "---> Add to " << mother->GetName() << " " << hname.str() << " with top copy number "
1026  << top_copy_number_offset + subdetector->GetCopyNo()<< G4endl;
1027  }
1028  }
1029  else {
1030  // name is the detector name followed by the copy_number_offset
1031  new G4PVPlacement(R_,(*T_),
1032  subdetector->GetLogicalVolume(),
1033  hname.str(),
1034  mother->GetLogicalVolume(),
1035  false,
1036  top_copy_number_offset + subdetector->GetCopyNo() );
1037  G4cout << "---> Add to " << mother->GetName() << " " << hname.str() << " with top copy number "
1038  << top_copy_number_offset + subdetector->GetCopyNo()<< G4endl;
1039  }
1040  */
1041 
1042 
1043  G4Transform3D Ta(subdetector->GetObjectRotationValue(),subdetector->GetObjectTranslation());
1044  //
1045  const G4RotationMatrix *pRot = R;
1046  if ( R == 0x0 ) {
1047  pRot =
1048  const_cast<G4RotationMatrix*>( &G4RotationMatrix::IDENTITY );
1049  }
1050  G4Transform3D Tm(*pRot,*T); G4Transform3D Tf = Tm * Ta;
1051  //
1052  if ( subdetector->GetLogicalVolume()->GetNoDaughters() == 0 ) {
1053  if ( subdetector->GetLogicalVolume()->GetSensitiveDetector() ) {
1054  new G4PVPlacement(Tf,
1055  subdetector->GetLogicalVolume(),
1056  hname.str(),
1057  mother->GetLogicalVolume(),
1058  false,
1059  top_copy_number_offset + subdetector->GetCopyNo() );
1060  G4cout << "---> Add to " << mother->GetName() << " " << hname.str() << " with top copy number "
1061  << top_copy_number_offset + subdetector->GetCopyNo()<< G4endl;
1062  }
1063  else {
1064  new G4PVPlacement(Tf,
1065  subdetector->GetLogicalVolume(),
1066  hname.str(),
1067  mother->GetLogicalVolume(),
1068  false,
1069  -1);
1070  G4cout << "---> Add to " << mother->GetName() << " " << hname.str() << " with top copy number -1 " << G4endl;
1071  }
1072  }
1073  else {
1074  // name is the detector name followed by the copy_number_offset
1075  new G4PVPlacement(Tf,
1076  subdetector->GetLogicalVolume(),
1077  hname.str(),
1078  mother->GetLogicalVolume(),
1079  false,
1080  top_copy_number_offset + subdetector->GetCopyNo() );
1081  G4cout << "---> Add to " << mother->GetName() << " " << hname.str() << " with top copy number "
1082  << top_copy_number_offset + subdetector->GetCopyNo()<< G4endl;
1083  }
1084  }
1085  return phycical_active.size();
1086 }
1087 
1088 
1089 G4int SToGS::DetectorFactory::Set(G4String basename, G4VPhysicalVolume *world, G4int copy_number_offset, const G4Transform3D *Tr,G4int main_copy_number)
1090 {
1091  if ( Tr ) {
1092  G4ThreeVector T = Tr->getTranslation(); G4RotationMatrix R = Tr->getRotation().inverse();
1093  return Set(basename,world,copy_number_offset,&T,&R,main_copy_number);
1094  }
1095  else return Set(basename,world,copy_number_offset,0x0,0x0,main_copy_number);
1096 }
1097 
1098 
1099 G4AssemblyVolume *SToGS::DetectorFactory::GetAssembly(G4String basename)
1100 {
1101  G4AssemblyVolume *theAssembly = 0x0; G4VPhysicalVolume *theDetector = 0x0, *subdetector; G4String detname, fullname;
1102 
1103  fullname = basename;
1104  fullname += ".gdml";
1105 
1106  // check is already loaded
1107  for (size_t i = 0; i < fLoadedAssembly.size(); i++) {
1108  if ( fLoadedAssembly[i].first == fullname ) {
1109  theAssembly = fLoadedAssembly[i].second;
1110  break;
1111  }
1112  }
1113  //
1114  if ( theAssembly == 0x0 ) {
1115  theDetector = Get(basename);
1116  if (theDetector == 0x0 ) {
1117  return 0x0;
1118  }
1119  theAssembly = new G4AssemblyVolume();
1120  //
1121  std::pair < G4String, G4AssemblyVolume *> p(fullname,theAssembly); // add the new assembly to the list of assembly
1122  fLoadedAssembly.push_back(p);
1123 
1124  // rebuilt the detector as an assembly
1125  for (G4int i = 0; i < theDetector->GetLogicalVolume()->GetNoDaughters(); i++) {
1126  subdetector = theDetector->GetLogicalVolume()->GetDaughter(i);
1127  // cout << " + " << subdetector->GetName() << " " << subdetector->GetCopyNo() << endl;
1128 
1129  G4Transform3D Tr = G4Transform3D(subdetector->GetObjectRotationValue(),subdetector->GetObjectTranslation());
1130  theAssembly->AddPlacedVolume( subdetector->GetLogicalVolume(), Tr );
1131  }
1132  }
1133  return theAssembly;
1134 }
1135 
1137 {
1138  if ( this == DetectorFactory::theMainFactory() ) {
1139  for (size_t i = 0; i < fSubFactory.size(); i++) {
1140  fSubFactory[i]->Clean();
1141  }
1142  G4LogicalVolumeStore::Clean(); G4PhysicalVolumeStore::Clean();
1143  }
1144  else {
1145  // clean the two inner collection of this factory and call G4 store manager to clean physical and volumes
1146  for (size_t i = 0; i < fLoadedPhysical.size(); i++) {
1147  fLoadedPhysical[i].second = 0x0;
1148  }
1149  fLoadedPhysical.resize(0);
1150  for (size_t i = 0; i < fLoadedAssembly.size(); i++) {
1151  delete fLoadedAssembly[i].second; fLoadedAssembly[i].second = 0x0;
1152  }
1153  fLoadedAssembly.resize(0);
1154  //
1155  }
1156 }
1157 
1158 G4VPhysicalVolume *SToGS::DetectorFactory::MakeVCR(G4String name, G4double HalfX, G4double HalfY, G4double HalfZ, G4int copy_number)
1159 {
1160  G4VPhysicalVolume *theRoom = 0x0; G4LogicalVolume *logicRoom; G4Box *room;
1161  G4RotationMatrix R;
1162  G4ThreeVector T;
1163  G4Transform3D Tr;
1164 
1165  // use a physical as a container to describe the detector
1166  room= new G4Box(name,HalfX,HalfY,HalfZ);
1167  logicRoom= new G4LogicalVolume(room, MaterialConsultant::theConsultant()->FindOrBuildMaterial("AIR"), name, 0, 0, 0);
1168 
1169  logicRoom->SetVisAttributes(G4VisAttributes::Invisible); // hide the world
1170 
1171  // Must place the World Physical volume unrotated at (0,0,0).
1172  theRoom = new G4PVPlacement(0, // no rotation
1173  G4ThreeVector(), // at (0,0,0)
1174  logicRoom, // its logical volume
1175  name, // its name
1176  0, // its mother volume
1177  false, // no boolean operations
1178  copy_number); // copy number
1179 
1180  return theRoom;
1181 }
1182 
1183 
1184 G4VPhysicalVolume * SToGS::DetectorFactory::MakeAnArrayFromFactory(G4String input_file)
1185 {
1186  G4VPhysicalVolume *theDetector = 0x0; std::vector< std::pair< G4AssemblyVolume *,G4VPhysicalVolume * > > all_assembly; G4bool is_new_assembly = false;
1187 
1188  // open the file containing the array to be built
1189  std::ifstream g4map(input_file.data());
1190  //
1191  if ( ! g4map.is_open() ) {
1192  return theDetector;
1193  }
1194  // first read the
1195 
1196  G4String key, detector_name, subdetector_name, aline, unit1, what, option_copy_number;
1197  G4double X, Y, Z, r_value;
1198 
1199  // logicals
1200  getline(g4map,aline);
1201  while ( g4map.good() ) {
1202 
1203  istringstream decode(aline); decode.clear(); G4bool is_Tr = false; // if line contains T means G4Transfrom should be used
1204 
1205  decode >> key ;
1206 
1207  if ( key.size() == 0 || key[0] == '#' ) {
1208  getline(g4map,aline);
1209  continue;
1210  }
1211  // change global copy number
1212  if ( key == "@" ) {
1213  G4int offset; decode >> offset >> option_copy_number;
1214 
1216 
1217  getline(g4map,aline);
1218  continue;
1219  }
1220  // imports an xml file, adds attributes and save
1221  if ( key == "i" ) {
1222  G4String gdmlfile, fullfactoryname, option_amap("*|*|*|0.5;0.5;0.5;0.5"), option_dmap("");
1223  decode >> gdmlfile >> fullfactoryname >> option_amap >> option_dmap;
1224 
1226  if ( factory ) {
1227  detector_name = SToGS::DetectorFactory::theMainFactory()->GetDetName(fullfactoryname);
1228  theDetector = factory->Import(gdmlfile, detector_name, option_amap, option_dmap);
1229  }
1230  getline(g4map,aline);
1231  continue;
1232  }
1233 
1234  if ( key == "[" && theDetector ) { // this starts a new assembly
1235  is_new_assembly = true;
1236  getline(g4map,aline);
1237  continue;
1238  }
1239  if ( key == "]" && theDetector ) { // this close a new assembly
1240 
1241  // treated @ the end i.e. after already built detector even if not in order in the input file
1242  for (size_t i = 0; i < all_assembly.size(); i++ ) {
1243  G4int nb_active = DoMap(all_assembly[i].first,all_assembly[i].second,SToGS::DetectorFactory::GetGCopyNb());
1245  }
1246  all_assembly.clear(); is_new_assembly = false;
1247  getline(g4map,aline);
1248  continue;
1249  }
1250 
1251  decode >> subdetector_name ;
1252 
1253  if ( key == "w" && decode.good() ) { // this is the name of the new setup/detector
1254 
1255  // use a physical as a container to describe the detector ... should be enough !
1256  theDetector = SToGS::DetectorFactory::theMainFactory()->Get(subdetector_name.data());
1257  if ( theDetector == 0x0 ) {
1258 
1259  decode >> X >> Y >> Z >> unit1 ;
1260  G4double do_unit =
1261  G4UnitDefinition::GetValueOf(unit1);
1262 
1263  theDetector = SToGS::DetectorFactory::MakeVCR(subdetector_name,do_unit*X,do_unit*Y,do_unit*Z,-1);
1264  }
1265  }
1266  if ( key == "+" && decode.good() && theDetector ) { // simply load the detector and add it
1267 
1268  G4RotationMatrix *R = new G4RotationMatrix();
1269 
1270  decode >> X >> Y >> Z >> unit1 ;
1271  G4double do_unit =
1272  G4UnitDefinition::GetValueOf(unit1);
1273  G4ThreeVector T(do_unit*X,do_unit*Y,do_unit*Z);
1274 
1275  while ( !decode.eof() ) {
1276  decode >> what;
1277  if ( what == "Rx" ) {
1278  decode >> r_value;
1279  R->rotateX(r_value*CLHEP::deg);
1280  }
1281  if ( what == "Ry" ) {
1282  decode >> r_value;
1283  R->rotateY(r_value*CLHEP::deg);
1284  }
1285  if ( what == "Rz" ) {
1286  decode >> r_value;
1287  R->rotateZ(r_value*CLHEP::deg);
1288  }
1289  if ( what == "Rt" ) {
1290  T = (*R) * T;
1291  }
1292  if ( what == "Tr" ) {
1293  is_Tr = true;
1294  }
1295  what = "";
1296  }
1297  SToGS::DetectorFactory *where_to_load = SToGS::DetectorFactory::GetFactory(subdetector_name);
1298  if ( where_to_load ) {
1299  G4int nb_added = 0;
1300  nb_added = where_to_load->Set(subdetector_name, theDetector, SToGS::DetectorFactory::GetGCopyNb(), &T, R);
1301  if ( nb_added < 0 ) { // volume not found in the Store
1302  cout << "[+..] Reading " << input_file << endl;
1303  cout << " *** !! *** " << subdetector_name << " DOES NOT EXIST IN THE FACTORY " << where_to_load->GetFactoryName() << endl;
1304  cout << "[..+] Reading " << input_file << endl;
1305  }
1307  // to do : Set return the number of active volumes
1308  }
1309  else {
1310  cout << "[+..] Reading " << input_file << endl;
1311  cout << " *** !! *** THE FACTORY DOES NOT EXIST " << endl;
1312  cout << "[..+] Reading " << input_file << endl;
1313  }
1314  }
1315 
1316  if ( key == "*" && decode.good() && theDetector && is_new_assembly ) { // this is a detector going to be replicated in space using the assembly mechanism
1317 
1318  G4VPhysicalVolume *detector = SToGS::DetectorFactory::theMainFactory()->Get(subdetector_name.data());
1319  G4AssemblyVolume *assembly = SToGS::DetectorFactory::theMainFactory()->GetAssembly(subdetector_name.data());
1320 
1321  if ( assembly ) {
1322 
1323  decode >> X >> Y >> Z >> unit1 ;
1324  G4double do_unit =
1325  G4UnitDefinition::GetValueOf(unit1);
1326  G4ThreeVector T(do_unit*X,do_unit*Y,do_unit*Z);
1327 
1328  // keep list of assemble required to build this new detector/setup
1329  G4bool in = false;
1330  for (size_t i = 0; i < all_assembly.size(); i++ ) {
1331  if ( assembly == all_assembly[i].first ) {
1332  in = true;
1333  break;
1334  }
1335  }
1336  if ( !in ) {
1337  all_assembly.push_back( std::pair< G4AssemblyVolume *, G4VPhysicalVolume *>(assembly,detector) );
1338  }
1339 
1340  G4RotationMatrix *R =new G4RotationMatrix();
1341 
1342  while ( !decode.eof() ) {
1343  decode >> what;
1344  if ( what == "Rx" ) {
1345  decode >> r_value;
1346  R->rotateX(r_value*CLHEP::deg);
1347  }
1348  if ( what == "Ry" ) {
1349  decode >> r_value;
1350  R->rotateY(r_value*CLHEP::deg);
1351  }
1352  if ( what == "Rz" ) {
1353  decode >> r_value;
1354  R->rotateZ(r_value*CLHEP::deg);
1355  }
1356  if ( what == "Rt" ) {
1357  T = (*R) * T;
1358  }
1359  if ( what == "Tr" ) {
1360  is_Tr = true;
1361  }
1362  what = "";
1363  }
1364 
1365  assembly->MakeImprint( theDetector->GetLogicalVolume(), T, R );
1366  }
1367  }
1368 
1369  getline(g4map,aline);
1370  }
1371 
1372  return theDetector;
1373 }
1374 
1375 
1377 #include "G4UIdirectory.hh"
1378 #include "G4UIcmdWithAString.hh"
1379 
1380 DFMessenger::DFMessenger():
1381  theDirectory(0x0),
1382  cmdToChangeSD(0x0),
1383  cmdToSaveInFactory(0x0)
1384 {
1385  theDirectory = new G4UIdirectory("/DetectoryFactory/");
1386  theDirectory->SetGuidance("To manage the DetectoryFactory");
1387 
1388  cmdToChangeSD = new G4UIcmdWithAString("/DetectoryFactory/changeSD", this);
1389  cmdToChangeSD->SetGuidance("Change Sensitivity of Sensitive detectors ");
1390  cmdToChangeSD->SetGuidance("Requires one string having the form XXX:YYY:ZZZ ");
1391  cmdToChangeSD->SetGuidance(" \t XXX is the volume name, could be * for all");
1392  cmdToChangeSD->SetGuidance(" \t YYY is the mat name, could be * ");
1393  cmdToChangeSD->SetGuidance(" \t ZZZ is the name of the new SD ");
1394 
1395  cmdToChangeSD->AvailableForStates(G4State_PreInit,G4State_Idle);
1396 
1397  cmdToSaveInFactory = new G4UIcmdWithAString("/DetectoryFactory/Save", this);
1398  cmdToSaveInFactory->SetGuidance("To save the current setup in MyStore ");
1399  cmdToSaveInFactory->SetGuidance("Requires one string which is the name of the setup to be stored");
1400  cmdToSaveInFactory->AvailableForStates(G4State_PreInit,G4State_Idle);
1401 }
1402 
1404 {
1405  delete theDirectory;
1406  // delete exportGEOMCmd; delete exportMAPCmd;
1407 }
1408 
1409 void DFMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
1410 {
1411  if( command == cmdToChangeSD ) {
1412  std::string modifier(newValue);
1413  if ( modifier[modifier.length()-1] != '^' )
1414  modifier += '^';
1416  }
1417 
1418  if( command == cmdToSaveInFactory ) {
1419  SToGS::DetectorFactory *where_to_store = SToGS::DetectorFactory::GetFactory("DetectorFactory/MyStore/");
1420  if ( where_to_store ) {
1421  G4VPhysicalVolume *world = 0x0;
1422  if ( G4TransportationManager::GetTransportationManager()
1423  && G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()) {
1424  world = G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume();
1425  }
1426  if ( world ) {
1427  world->SetName(newValue); world->GetLogicalVolume()->SetName(newValue);
1428  where_to_store->Store(world);
1429  }
1430  else {
1431  G4cout << " Cannot save world in MyStore ! " << G4endl;
1432  }
1433  }
1434  }
1435 
1436 }
1438 
1439 
1440 
1441 
1442 
1443 
1444 
1445 
G4int Set(G4String basename, G4VPhysicalVolume *world, G4int copy_number_offset, const G4ThreeVector *T=0x0, const G4RotationMatrix *R=0x0, G4int main_copy_number=0)
to be used once a detector is fully contructed to simply place it in the world
static G4VPhysicalVolume * MakeVCR(G4String name, G4double HalfX=5.0 *CLHEP::m, G4double HalfY=5.0 *CLHEP::m, G4double HalfZ=5.0 *CLHEP::m, G4int copy=-1)
make a cubic world
the Messenger for the Detector Factory
void StoreMap(std::ofstream &amap, std::ofstream &dmap, std::vector< G4LogicalVolume * > &logical_stored, std::vector< G4VPhysicalVolume * > &physical_stored, std::vector< G4VPhysicalVolume * > &physical_active, G4VPhysicalVolume *theDetector)
recursively called in the tree struture
static DetectorFactory * GetFactory(G4String fullname)
get the specific factory for a full name to a file
void CollectVolumes(TGeoNode *theDetector, TObjArray &logical_stored, TObjArray &phycical_stored)
From the Full geometry, extract the logical and physical [nodes] volumes.
Definition: BrowserFactory.C:8
void Clean()
clear factory i.e. in memory collections of physicals and assemblies
G4String GetDetName(const G4String &path) const
Get detector name from full path to the gdml file.
void MakeInStore(G4String name, G4String version_string)
build in store a particular detector from its names and version. i.e. call th Make method of the sub ...
virtual void Store(G4VPhysicalVolume *)
Store in the sub-factory the given physical volume.
virtual G4VPhysicalVolume * Get(G4String basename)
search for a detector in DetectorFactory
static G4VSensitiveDetector * GetSD(G4String opt, const char sd_type= 'S')
Get a particular SD. S means a SD while s is for Scorers.
static G4int AddGCopyNb()
global copy number, used to set copy number once building detector. Not protected for MT since in pri...
static DetectorFactory * theMainFactory()
to get the main factory
void SetNewValue(G4UIcommand *, G4String)
virtual G4VPhysicalVolume * MakeAnArrayFromFactory(G4String input_file)
built an array from the factory using the given input file
G4String GetFileName(G4String detname, G4String extention)
compute name of the file to store/read information
virtual G4int ReMap(G4VPhysicalVolume *adetector, G4int offset)
for the given volume, it changes all copy number of active volumes by starting with offset ...
static G4int SetGCopyNb(G4int val)
static G4VSensitiveDetector * GetCopClusterSD(G4String name="/SToGS/SD/CopCluster")
to get a general SToGS Calorimeter. In Multi-threading mode, return a new instance otherwise a global...
static void CollectVolumes(G4VPhysicalVolume *theDetector, std::vector< G4LogicalVolume * > &logical_stored, std::vector< G4VPhysicalVolume * > &physical_stored, std::vector< G4VPhysicalVolume * > &physical_active)
From the given physical volume, it collects into collection all logical (sensitive) and physical volu...
virtual void GetAttributes(G4String basename, G4bool do_amap=true, G4bool do_dmap=false)
Read the amap file and apply atributes to the detector. if not found, it creates a deefault one from ...
Base Factory. This is a container of sub-factories.
void AssemblyRename(G4AssemblyVolume *assembly, const G4String &volume_to_find) const
rename physical volume produced by the assembly
G4String GetFactoryName() const
virtual void MakeStore()
build the default store i.e. all the detectors. Here It calls MakeStore for all registered sub factor...
static G4VSensitiveDetector * GetTrackerSD(G4String name="/SToGS/SD/Tracker")
to get a general SToGS tracker. In Multi-threading mode, return a new instance otherwise a global one...
G4int DoMap(G4AssemblyVolume *assembly, G4VPhysicalVolume *volume_used_to_built_assembly, G4int copy_number_offset=0) const
remap all the physical volumes produced by the Imprint method.
G4VPhysicalVolume * Import(G4String gdmlfile, G4String detname, const G4String &opt_amap, const G4String &opt_dmap)
import a gdml file (extention to ascii ?) into factory. See Active for opt_amap option ...
void StreamTouchable(std::ofstream &dmap, G4String)
extrac from the name of the detector the touchable part
static void SetActive(G4LogicalVolume *pv, const G4String &option="*|*|*|0.5;0.5;0.5;0.5")
Set to the given logical volume some attributs (sensitive, color) depending of the given option...
static void ChangeSD(G4String opt, G4VPhysicalVolume *top=0x0)
Change some SD detector into an other type of SD. Opt is used eventually to filter on the name of the...
G4AssemblyVolume * GetAssembly(G4String basename)