G4ReflectionFactory.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // 
00030 // Class G4ReflectionFactory Implementation
00031 //
00032 // Decomposition of a general transformation
00033 // that can include reflection in a "reflection-free" transformation:
00034 // 
00035 // x(inM') = TG*x(inM)         TG - general transformation
00036 //         = T*(R*x(inM))      T  - "reflection-free" transformation
00037 //         = T* x(inReflM)   
00038 //
00039 // Daughters transformation:
00040 // When a volume V containing daughter D with transformation TD
00041 // is placed in mother M with a general tranformation TGV,
00042 // the TGV is decomposed,
00043 // new reflected volume ReflV containing a new daughter ReflD
00044 // with reflected transformation ReflTD is created:
00045 // 
00046 // x(inV) = TD * x(inD);
00047 // x(inM) = TGV * x(inV) 
00048 //        = TV * R * x(inV) 
00049 //        = TV * R * TD * x(inD)
00050 //        = TV * R*TD*R-1 * R*x(inD)
00051 //        = TV * ReflTD * x(inReflD)
00052 
00053 // Author: Ivana Hrivnacova, 16.10.2001  (Ivana.Hrivnacova@cern.ch)
00054 // --------------------------------------------------------------------
00055 
00056 #include "G4ReflectionFactory.hh"
00057 #include "G4ReflectedSolid.hh"
00058 #include "G4Region.hh" 
00059 #include "G4LogicalVolume.hh"  
00060 #include "G4PVPlacement.hh"  
00061 #include "G4PVReplica.hh"  
00062 #include "G4VPVDivisionFactory.hh"
00063 #include "G4GeometryTolerance.hh"
00064 
00065 G4ReflectionFactory* G4ReflectionFactory::fInstance = 0;
00066 const G4String  G4ReflectionFactory::fDefaultNameExtension = "_refl";
00067 const G4Scale3D G4ReflectionFactory::fScale = G4ScaleZ3D(-1.0);
00068 
00069 //_____________________________________________________________________________
00070 
00071 G4ReflectionFactory* G4ReflectionFactory::Instance() 
00072 {
00073   // Static singleton access method.
00074   // ---
00075 
00076   if (!fInstance) { fInstance = new G4ReflectionFactory(); }
00077 
00078   return fInstance;
00079 }  
00080 
00081 //_____________________________________________________________________________
00082 
00083 G4ReflectionFactory::G4ReflectionFactory()
00084   : fVerboseLevel(0),
00085     fNameExtension(fDefaultNameExtension)    
00086 {
00087   // Protected singleton constructor.
00088   // ---
00089 
00090   fScalePrecision = 10.
00091                   * G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
00092   fInstance = this;
00093 }
00094 
00095 //_____________________________________________________________________________
00096 
00097 G4ReflectionFactory::~G4ReflectionFactory()
00098 {
00099   delete fInstance;
00100 }
00101 
00102 //
00103 // public methods
00104 //
00105 
00106 //_____________________________________________________________________________
00107 
00108 G4PhysicalVolumesPair
00109 G4ReflectionFactory::Place( const G4Transform3D& transform3D,
00110                             const G4String&      name,
00111                                   G4LogicalVolume* LV,
00112                                   G4LogicalVolume* motherLV,
00113                                   G4bool  isMany, 
00114                                   G4int   copyNo,
00115                                   G4bool  surfCheck)
00116 {
00117   // Evaluates the passed transformation; if it contains reflection
00118   // it performs its decomposition, creates new reflected solid and
00119   // logical volume (or retrieves them from a map if the reflected
00120   // objects were already created), transforms the daughters (if present)
00121   // and place it in the given mother.
00122   // The result is a pair of physical volumes;
00123   // the second physical volume is a placement in a reflected mother
00124   // - or 0 if mother LV was not reflected.
00125   // ---
00126 
00127   if (fVerboseLevel>0)
00128   {
00129     G4cout << "Place " << name << " lv " << LV << " "
00130            << LV->GetName() << G4endl;
00131   }  
00132 
00133   // decompose transformation
00134   G4Scale3D     scale;
00135   G4Rotate3D    rotation;
00136   G4Translate3D translation;
00137 
00138   transform3D.getDecomposition(scale, rotation, translation);
00139   G4Transform3D pureTransform3D = translation * rotation;
00140   
00141   //PrintTransform(transform3D);
00142   //PrintTransform(pureTransform3D);
00143 
00144   // check that scale correspond to fScale
00145   //
00146   CheckScale(scale);
00147   
00148   //
00149   // reflection IS NOT present in transform3D 
00150   //
00151 
00152   if (! IsReflection(scale))
00153   {
00154     if (fVerboseLevel>0)
00155       G4cout << "Scale positive" << G4endl;
00156 
00157     G4VPhysicalVolume* pv1
00158       =  new G4PVPlacement(pureTransform3D, LV, name,
00159                            motherLV, isMany, copyNo, surfCheck);
00160  
00161     G4VPhysicalVolume* pv2 = 0;
00162     if (G4LogicalVolume* reflMotherLV = GetReflectedLV(motherLV))
00163     {
00164       // if mother was reflected
00165       // reflect this LV and place it in reflected mother
00166       
00167       pv2 = new G4PVPlacement(fScale * (pureTransform3D * fScale.inverse()),
00168                               ReflectLV(LV, surfCheck), name, reflMotherLV,
00169                               isMany, copyNo, surfCheck);
00170     }
00171     
00172     return G4PhysicalVolumesPair(pv1, pv2);            
00173   }         
00174            
00175   //
00176   //  reflection IS present in transform3D
00177   //
00178 
00179   if (fVerboseLevel>0)
00180     G4cout << "scale negative" << G4endl;
00181 
00182   G4VPhysicalVolume* pv1
00183     = new G4PVPlacement(pureTransform3D, ReflectLV(LV, surfCheck), name,
00184                         motherLV, isMany, copyNo, surfCheck);
00185 
00186   G4VPhysicalVolume* pv2 = 0;
00187   if (G4LogicalVolume* reflMotherLV = GetReflectedLV(motherLV))
00188   {
00189 
00190     // if mother was reflected
00191     // place the refLV consituent in reflected mother
00192 
00193     pv2 =  new G4PVPlacement(fScale * (pureTransform3D * fScale.inverse()),
00194                              LV, name, reflMotherLV, isMany, copyNo, surfCheck);
00195   }
00196 
00197   return G4PhysicalVolumesPair(pv1, pv2);  
00198 }           
00199 
00200 
00201 //_____________________________________________________________________________
00202 
00203 G4PhysicalVolumesPair
00204 G4ReflectionFactory::Replicate(const G4String& name, 
00205                                      G4LogicalVolume* LV,
00206                                      G4LogicalVolume* motherLV,
00207                                      EAxis axis, 
00208                                      G4int nofReplicas, 
00209                                      G4double width,
00210                                      G4double offset)
00211 {
00212   // Creates replica in given mother.
00213   // The result is a pair of physical volumes;
00214   // the second physical volume is a replica in a reflected mother
00215   // - or 0 if mother LV was not reflected.
00216   // ---
00217 
00218   if (fVerboseLevel>0)
00219   {
00220     G4cout << "Replicate " << name << " lv " << LV << " " 
00221            << LV->GetName() << G4endl;
00222   }  
00223 
00224   G4VPhysicalVolume* pv1
00225     = new G4PVReplica(name, LV, motherLV, axis, nofReplicas, width, offset);
00226  
00227   G4VPhysicalVolume* pv2 = 0;
00228   if (G4LogicalVolume* reflMotherLV = GetReflectedLV(motherLV))
00229   {
00230     // if mother was reflected
00231     // reflect the LV and replicate it in reflected mother
00232     
00233     pv2 = new G4PVReplica(name, ReflectLV(LV), reflMotherLV, 
00234                           axis, nofReplicas, width, offset); 
00235   }
00236     
00237   return G4PhysicalVolumesPair(pv1, pv2);            
00238 }         
00239         
00240 //_____________________________________________________________________________
00241 
00242 G4PhysicalVolumesPair
00243 G4ReflectionFactory::Divide(const G4String& name, 
00244                                   G4LogicalVolume* LV,
00245                                   G4LogicalVolume* motherLV,
00246                                   EAxis axis, 
00247                                   G4int nofDivisions, 
00248                                   G4double width,
00249                                   G4double offset)
00250 {
00251   // Creates division in the given mother.
00252   // The result is a pair of physical volumes;
00253   // the second physical volume is a division in a reflected mother
00254   // or 0 if mother LV was not reflected.
00255   // ---
00256 
00257   if (fVerboseLevel>0)
00258   {
00259     G4cout << "Divide " << name << " lv " << LV << " " 
00260            << LV->GetName() << G4endl;
00261   }  
00262 
00263   G4VPVDivisionFactory* divisionFactory = GetPVDivisionFactory();
00264 
00265   G4VPhysicalVolume* pv1 = divisionFactory
00266       ->CreatePVDivision(name, LV, motherLV, axis, nofDivisions, width, offset);
00267  
00268   G4VPhysicalVolume* pv2 = 0;
00269   if (G4LogicalVolume* reflMotherLV = GetReflectedLV(motherLV))
00270   {
00271     // if mother was reflected
00272     // reflect the LV and replicate it in reflected mother
00273     
00274     pv2 = divisionFactory->CreatePVDivision(name, ReflectLV(LV), reflMotherLV, 
00275                                             axis, nofDivisions, width, offset); 
00276   }
00277     
00278   return G4PhysicalVolumesPair(pv1, pv2);            
00279 }         
00280         
00281              
00282 //_____________________________________________________________________________
00283 
00284 G4PhysicalVolumesPair
00285 G4ReflectionFactory::Divide(const G4String& name, 
00286                                   G4LogicalVolume* LV,
00287                                   G4LogicalVolume* motherLV,
00288                                   EAxis axis, 
00289                                   G4int nofDivisions, 
00290                                   G4double offset)
00291 {
00292   // Creates division in the given mother.
00293   // The result is a pair of physical volumes;
00294   // the second physical volume is a division in a reflected mother
00295   // or 0 if mother LV was not reflected.
00296   // ---
00297 
00298   if (fVerboseLevel>0)
00299   {
00300     G4cout << "Divide " << name << " lv " << LV << " " 
00301            << LV->GetName() << G4endl;
00302   }  
00303 
00304   G4VPVDivisionFactory* divisionFactory = GetPVDivisionFactory();
00305 
00306   G4VPhysicalVolume* pv1 = divisionFactory
00307       ->CreatePVDivision(name, LV, motherLV, axis, nofDivisions, offset);
00308  
00309   G4VPhysicalVolume* pv2 = 0;
00310   if (G4LogicalVolume* reflMotherLV = GetReflectedLV(motherLV))
00311   {
00312     // if mother was reflected
00313     // reflect the LV and replicate it in reflected mother
00314     
00315     pv2 = divisionFactory->CreatePVDivision(name, ReflectLV(LV), reflMotherLV, 
00316                                             axis, nofDivisions, offset); 
00317   }
00318     
00319   return G4PhysicalVolumesPair(pv1, pv2);            
00320 }         
00321         
00322              
00323 //_____________________________________________________________________________
00324 
00325 G4PhysicalVolumesPair
00326 G4ReflectionFactory::Divide(const G4String& name, 
00327                                   G4LogicalVolume* LV,
00328                                   G4LogicalVolume* motherLV,
00329                                   EAxis axis, 
00330                                   G4double width,
00331                                   G4double offset)
00332 {
00333   // Creates division in the given mother.
00334   // The result is a pair of physical volumes;
00335   // the second physical volume is a division in a reflected mother
00336   // or 0 if mother LV was not reflected.
00337   // ---
00338 
00339   if (fVerboseLevel>0)
00340   {
00341     G4cout << "Divide " << name << " lv " << LV << " " 
00342            << LV->GetName() << G4endl;
00343   }  
00344 
00345   G4VPVDivisionFactory* divisionFactory = GetPVDivisionFactory();
00346 
00347   G4VPhysicalVolume* pv1 = divisionFactory
00348     -> CreatePVDivision(name, LV, motherLV, axis, width, offset);
00349  
00350   G4VPhysicalVolume* pv2 = 0;
00351   if (G4LogicalVolume* reflMotherLV = GetReflectedLV(motherLV))
00352   {
00353     // if mother was reflected
00354     // reflect the LV and replicate it in reflected mother
00355     
00356     pv2 = divisionFactory->CreatePVDivision(name, ReflectLV(LV), reflMotherLV, 
00357                                             axis, width, offset); 
00358   }
00359     
00360   return G4PhysicalVolumesPair(pv1, pv2);            
00361 }         
00362         
00363              
00364 //
00365 // private methods
00366 //
00367 
00368 //_____________________________________________________________________________
00369 
00370 G4LogicalVolume* G4ReflectionFactory::ReflectLV(G4LogicalVolume* LV,
00371                                                 G4bool surfCheck) 
00372 {
00373   // Gets/creates the reflected solid and logical volume
00374   // and copies + transforms LV daughters.
00375   // ---
00376 
00377   G4LogicalVolume* refLV = GetReflectedLV(LV);
00378 
00379   if (!refLV)
00380   {
00381 
00382     // create new (reflected) objects
00383     //
00384     refLV = CreateReflectedLV(LV);
00385         
00386     // process daughters  
00387     //
00388     ReflectDaughters(LV, refLV, surfCheck);
00389 
00390     // check if to be set as root region
00391     //
00392     if (LV->IsRootRegion())
00393     {
00394        LV->GetRegion()->AddRootLogicalVolume(refLV);
00395     }
00396   }
00397 
00398   return refLV;
00399 }
00400 
00401 //_____________________________________________________________________________
00402 
00403 G4LogicalVolume* G4ReflectionFactory::CreateReflectedLV(G4LogicalVolume* LV) 
00404 {
00405   // Creates the reflected solid and logical volume
00406   // and add the logical volumes pair in the maps.
00407   // ---
00408 
00409   // consistency check
00410   //
00411   if (fReflectedLVMap.find(LV) != fReflectedLVMap.end())
00412   {
00413     std::ostringstream message;
00414     message << "Invalid reflection for volume: "
00415            << LV->GetName() << G4endl
00416            << "Cannot be applied to a volume already reflected !";
00417     G4Exception("G4ReflectionFactory::CreateReflectedLV()",
00418                 "GeomVol0002", FatalException, message);
00419   }        
00420               
00421   G4VSolid* refSolid 
00422     = new G4ReflectedSolid(LV->GetSolid()->GetName() + fNameExtension,
00423                            LV->GetSolid(), fScale);
00424       
00425   G4LogicalVolume* refLV
00426     = new G4LogicalVolume(refSolid, 
00427                           LV->GetMaterial(),                 
00428                           LV->GetName() + fNameExtension,
00429                           LV->GetFieldManager(),
00430                           LV->GetSensitiveDetector(),
00431                           LV->GetUserLimits());
00432   refLV->SetVisAttributes(LV->GetVisAttributes());  // vis-attributes
00433   refLV->SetBiasWeight(LV->GetBiasWeight());        // biasing weight
00434   if (LV->IsRegion())
00435   {
00436     refLV->SetRegion(LV->GetRegion());              // set a region in case
00437   }
00438 
00439   fConstituentLVMap[LV] = refLV;
00440   fReflectedLVMap[refLV] = LV;
00441 
00442   return refLV;        
00443 }
00444 
00445 //_____________________________________________________________________________
00446 
00447 void G4ReflectionFactory::ReflectDaughters(G4LogicalVolume* LV, 
00448                                            G4LogicalVolume* refLV,
00449                                            G4bool surfCheck)
00450 {
00451   // Reflects daughters recursively.
00452   // ---
00453 
00454   if (fVerboseLevel>0)
00455   {
00456     G4cout << "G4ReflectionFactory::ReflectDaughters(): " 
00457            << LV->GetNoDaughters() << " of " << LV->GetName() << G4endl;
00458   }     
00459 
00460   for (G4int i=0; i<LV->GetNoDaughters(); i++)
00461   {
00462     G4VPhysicalVolume* dPV = LV->GetDaughter(i);
00463     
00464     if (! dPV->IsReplicated())
00465     {
00466       ReflectPVPlacement(dPV, refLV, surfCheck); 
00467     }  
00468     else if (! dPV->GetParameterisation())
00469     {
00470       ReflectPVReplica(dPV, refLV); 
00471     }  
00472     else if (G4VPVDivisionFactory::Instance() &&
00473              G4VPVDivisionFactory::Instance()->IsPVDivision(dPV))
00474     {
00475       ReflectPVDivision(dPV, refLV); 
00476     }  
00477     else
00478     {
00479       ReflectPVParameterised(dPV, refLV, surfCheck); 
00480     }
00481   }
00482 }
00483 
00484 //_____________________________________________________________________________
00485 
00486 void G4ReflectionFactory::ReflectPVPlacement(G4VPhysicalVolume* dPV, 
00487                                              G4LogicalVolume* refLV,
00488                                              G4bool surfCheck)
00489 {
00490   // Copies and transforms daughter of PVPlacement type of
00491   // a constituent volume into a reflected volume. 
00492   // ---
00493 
00494   G4LogicalVolume* dLV = dPV->GetLogicalVolume();
00495 
00496   // update daughter transformation
00497   //
00498   G4Transform3D dt(dPV->GetObjectRotationValue(), dPV->GetObjectTranslation());
00499   dt = fScale * (dt * fScale.inverse());
00500 
00501   G4LogicalVolume* refDLV;
00502   
00503   if (fVerboseLevel>0) 
00504     G4cout << "Daughter: " << dPV << "  " << dLV->GetName();
00505   
00506   if (!IsReflected(dLV))
00507   {
00508 
00509     if (fVerboseLevel>0) 
00510       G4cout << " will be reflected." << G4endl;
00511 
00512     // get reflected volume if already created    //
00513     refDLV = GetReflectedLV(dLV); 
00514 
00515     if (!refDLV)
00516     {
00517       // create new daughter solid and logical volume
00518       //
00519       refDLV = CreateReflectedLV(dLV); 
00520   
00521       // recursive call
00522       //
00523       ReflectDaughters(dLV, refDLV, surfCheck);   
00524     }  
00525 
00526     // create new daughter physical volume
00527     // with updated transformation
00528 
00529     new G4PVPlacement(dt, refDLV, dPV->GetName(), refLV, 
00530                       dPV->IsMany(), dPV->GetCopyNo(), surfCheck); 
00531 
00532   } 
00533   else
00534   {
00535     if (fVerboseLevel>0) 
00536       G4cout << " will be reconstitued." << G4endl;
00537 
00538     refDLV = GetConstituentLV(dLV); 
00539 
00540     new G4PVPlacement(dt, refDLV, dPV->GetName(), refLV, 
00541                       dPV->IsMany(), dPV->GetCopyNo(), surfCheck); 
00542   }       
00543 }    
00544 
00545 //_____________________________________________________________________________
00546 
00547 void G4ReflectionFactory::ReflectPVReplica(G4VPhysicalVolume* dPV, 
00548                                            G4LogicalVolume* refLV)
00549 {
00550   // Copies and transforms daughter of PVReplica type of
00551   // a constituent volume into a reflected volume. 
00552   // ---
00553 
00554   G4LogicalVolume* dLV = dPV->GetLogicalVolume();
00555 
00556   // get replication data
00557   //
00558   EAxis axis;
00559   G4int nofReplicas;
00560   G4double width;
00561   G4double offset;
00562   G4bool consuming;
00563 
00564   dPV->GetReplicationData(axis, nofReplicas, width, offset, consuming);
00565 
00566   G4LogicalVolume* refDLV;
00567   
00568   if (fVerboseLevel>0) 
00569     G4cout << "Daughter: " << dPV << "  " << dLV->GetName();
00570   
00571   if (!IsReflected(dLV))
00572   {
00573     if (fVerboseLevel>0) 
00574       G4cout << " will be reflected." << G4endl;
00575 
00576     // get reflected volume if already created
00577     //
00578     refDLV = GetReflectedLV(dLV); 
00579 
00580     if (!refDLV)
00581     {
00582       // create new daughter solid and logical volume
00583       //
00584       refDLV = CreateReflectedLV(dLV); 
00585   
00586       // recursive call
00587       //
00588       ReflectDaughters(dLV, refDLV); 
00589     }     
00590         
00591     // create new daughter replica
00592     //
00593     new G4PVReplica(dPV->GetName(), refDLV, refLV, 
00594                     axis, nofReplicas, width, offset);
00595   }
00596   else
00597   {
00598     if (fVerboseLevel>0) 
00599       G4cout << " will be reconstitued." << G4endl;
00600 
00601     refDLV = GetConstituentLV(dLV); 
00602 
00603     new G4PVReplica(dPV->GetName(), refDLV, refLV, 
00604                     axis, nofReplicas, width, offset); 
00605   }       
00606 }
00607 
00608 //_____________________________________________________________________________
00609 
00610 void G4ReflectionFactory::ReflectPVDivision(G4VPhysicalVolume* dPV, 
00611                                             G4LogicalVolume* refLV)
00612 {
00613   // Copies and transforms daughter of PVDivision type of
00614   // a constituent volume into a reflected volume. 
00615   // ---
00616 
00617   G4VPVDivisionFactory* divisionFactory = GetPVDivisionFactory();
00618 
00619   G4LogicalVolume* dLV = dPV->GetLogicalVolume();
00620 
00621   // get parameterisation data
00622   //
00623   G4VPVParameterisation* param = dPV->GetParameterisation();
00624 
00625   G4LogicalVolume* refDLV;
00626   
00627   if (fVerboseLevel>0) 
00628     G4cout << "Daughter: " << dPV << "  " << dLV->GetName();
00629   
00630   if (!IsReflected(dLV))
00631   {
00632     if (fVerboseLevel>0) 
00633       G4cout << " will be reflected." << G4endl;
00634 
00635     // get reflected volume if already created
00636     //
00637     refDLV = GetReflectedLV(dLV); 
00638 
00639     if (!refDLV)
00640     {
00641       // create new daughter solid and logical volume
00642       //
00643       refDLV = CreateReflectedLV(dLV); 
00644   
00645       // recursive call
00646       //
00647       ReflectDaughters(dLV, refDLV); 
00648     }     
00649         
00650     // create new daughter replica
00651     //
00652     divisionFactory->CreatePVDivision(dPV->GetName(), refDLV, refLV, param);
00653   }
00654   else
00655   {
00656     if (fVerboseLevel>0) 
00657       G4cout << " will be reconstitued." << G4endl;
00658 
00659     refDLV = GetConstituentLV(dLV); 
00660 
00661     divisionFactory->CreatePVDivision(dPV->GetName(), refDLV, refLV, param); 
00662   }       
00663 }
00664 
00665 //_____________________________________________________________________________
00666 
00667 void G4ReflectionFactory::ReflectPVParameterised(G4VPhysicalVolume* dPV, 
00668                                                  G4LogicalVolume*, G4bool)
00669 {
00670   // Not implemented.
00671   // Should copy and transform daughter of PVReplica type of
00672   // a constituent volume into a reflected volume. 
00673   // ---
00674 
00675   std::ostringstream message;
00676   message << "Not yet implemented. Volume: " << dPV->GetName() << G4endl
00677           << "Reflection of parameterised volumes is not yet implemented.";
00678   G4Exception("G4ReflectionFactory::ReflectPVParameterised()",
00679               "GeomVol0001", FatalException, message);
00680 }
00681 
00682 //_____________________________________________________________________________
00683 
00684 G4LogicalVolume*
00685 G4ReflectionFactory::GetConstituentLV(G4LogicalVolume* reflLV) const
00686 {              
00687   // Returns the consituent volume of the given reflected volume,
00688   // 0 if the given reflected volume was not found.
00689   // ---
00690 
00691   LogicalVolumesMapIterator it = fReflectedLVMap.find(reflLV);
00692 
00693   if (it == fReflectedLVMap.end()) return 0;
00694 
00695   return (*it).second;
00696 }        
00697 
00698 //_____________________________________________________________________________
00699 
00700 G4LogicalVolume*
00701 G4ReflectionFactory::GetReflectedLV(G4LogicalVolume* lv) const
00702 {              
00703   // Returns the reflected volume of the given consituent volume,
00704   // 0 if the given volume was not reflected.
00705   // ---
00706 
00707   LogicalVolumesMapIterator it = fConstituentLVMap.find(lv);
00708 
00709   if (it == fConstituentLVMap.end()) return 0;
00710 
00711   return (*it).second;
00712 }        
00713 
00714 //_____________________________________________________________________________
00715 
00716 G4bool G4ReflectionFactory::IsConstituent(G4LogicalVolume* lv) const
00717 {
00718   // Returns true if the given volume has been already reflected
00719   // (is in the map of constituent volumes).
00720   // ---
00721 
00722   return (fConstituentLVMap.find(lv) != fConstituentLVMap.end());
00723 }  
00724 
00725 //_____________________________________________________________________________
00726 
00727 G4bool G4ReflectionFactory::IsReflected(G4LogicalVolume* lv) const
00728 {
00729   // Returns true if the given volume is a reflected volume
00730   // (is in the map reflected  volumes).
00731   // ---
00732 
00733   return (fReflectedLVMap.find(lv) != fReflectedLVMap.end());
00734 }  
00735 
00736 //_____________________________________________________________________________
00737 
00738 G4bool G4ReflectionFactory::IsReflection(const G4Scale3D& scale) const
00739 {
00740   // Returns true if the scale is negative, false otherwise.
00741   // ---
00742 
00743   if (scale(0,0)*scale(1,1)*scale(2,2) < 0.)
00744     return true;
00745   else 
00746     return false;  
00747 }
00748 
00749 //_____________________________________________________________________________
00750 
00751 const G4ReflectedVolumesMap&
00752 G4ReflectionFactory::GetReflectedVolumesMap() const
00753 {
00754   return fReflectedLVMap;
00755 }
00756 
00757 //_____________________________________________________________________________
00758 
00759 void
00760 G4ReflectionFactory::Reset()
00761 {
00762   fConstituentLVMap.~map();
00763   fReflectedLVMap.~map();
00764 }
00765 
00766 //_____________________________________________________________________________
00767 
00768 void G4ReflectionFactory::PrintConstituentLVMap()
00769 {
00770   // temporary - for debugging purpose
00771   // ---
00772 
00773   LogicalVolumesMapIterator it;
00774   for (it = fConstituentLVMap.begin(); it != fConstituentLVMap.end(); it++)
00775   {
00776     G4cout << "lv: " << (*it).first << "  lv_refl: " << (*it).second << G4endl;
00777   }
00778   G4cout << G4endl;
00779 }  
00780 
00781 //_____________________________________________________________________________
00782 
00783 void G4ReflectionFactory::CheckScale(const G4Scale3D& scale) const
00784 {
00785   // Check if scale correspond to fScale,
00786   // if not give exception.
00787   // ---
00788 
00789   if (!IsReflection(scale)) return;
00790   
00791   G4double diff = 0.;
00792   for (G4int i=0; i<4; i++)
00793     for (G4int j=0; j<4; j++) 
00794       diff += std::abs(scale(i,j) - fScale(i,j));  
00795 
00796   if (diff > fScalePrecision)
00797   {
00798     std::ostringstream message;
00799     message << "Unexpected scale in input !" << G4endl
00800             << "        Difference: " << diff;
00801     G4Exception("G4ReflectionFactory::CheckScale()",
00802                 "GeomVol0002", FatalException, message);
00803   }
00804 }    
00805 
00806 //_____________________________________________________________________________
00807 
00808 G4VPVDivisionFactory* G4ReflectionFactory::GetPVDivisionFactory() const
00809 {
00810   // Returns the G4PVDivisionFactory instance if it exists,
00811   // otherwise gives exception 
00812   // ---
00813 
00814   G4VPVDivisionFactory* divisionFactory = G4VPVDivisionFactory::Instance();
00815   if (!divisionFactory)
00816   {
00817     std::ostringstream message;
00818     message << "A concrete G4PVDivisionFactory instantiated is required !"
00819             << G4endl
00820             << "        It has been requested to reflect divided volumes."
00821             << G4endl
00822             << "        In this case, it is required to instantiate a concrete"
00823             << G4endl
00824             << "        factory G4PVDivisionFactory in your program -before-"
00825             << G4endl
00826             << "        executing the reflection !";
00827      G4Exception("G4ReflectionFactory::GetPVDivisionFactory()",
00828                  "GeomVol0002", FatalException, message);
00829   }
00830   
00831   return divisionFactory;
00832 }  
00833 
00834 //_____________________________________________________________________________
00835 
00836 void G4ReflectionFactory::SetScalePrecision(G4double scaleValue)
00837 {
00838   fScalePrecision = scaleValue;
00839 }
00840 
00841 //_____________________________________________________________________________
00842 
00843 G4double G4ReflectionFactory::GetScalePrecision() const
00844 {
00845   return fScalePrecision;
00846 }
00847 
00848 //_____________________________________________________________________________
00849 
00850 void G4ReflectionFactory::SetVerboseLevel(G4int verboseLevel)
00851 {
00852   fVerboseLevel = verboseLevel;
00853 }
00854           
00855 //_____________________________________________________________________________
00856 
00857 G4int G4ReflectionFactory::GetVerboseLevel() const
00858 {
00859   return fVerboseLevel;
00860 }
00861 
00862 //_____________________________________________________________________________
00863 
00864 void G4ReflectionFactory::SetVolumesNameExtension(const G4String& nameExtension)
00865 {
00866   fNameExtension = nameExtension;
00867 }
00868           
00869 //_____________________________________________________________________________
00870 
00871 const G4String& G4ReflectionFactory::GetVolumesNameExtension() const
00872 {
00873   return fNameExtension;
00874 }
00875           
00876 /*
00877   // placement with decomposed transformation
00878 
00879   G4VPhysicalVolume* pv1
00880     =  new G4PVPlacement(new G4RotationMatrix(rotation.getRotation().inverse()),
00881                          translation.getTranslation(),
00882             refLV, name, motherLV, isMany, copyNo);
00883 */

Generated on Mon May 27 17:49:43 2013 for Geant4 by  doxygen 1.4.7