MollerDetectorConstruction.cc

Go to the documentation of this file.
00001 
00002 
00003 #include "MollerDetectorConstruction.hh"
00004 #include "MollerDetectorMessenger.hh"
00005 
00006 #include "MollerDetectorSD.hh"
00007 
00008 #include "G4FieldManager.hh"
00009 #include "G4TransportationManager.hh"
00010 
00011 #include "G4Material.hh"
00012 #include "G4Element.hh"
00013 #include "G4NistManager.hh"
00014 
00015 #include "G4VSolid.hh"
00016 #include "G4Box.hh"
00017 #include "G4Tubs.hh"
00018 #include "G4Cons.hh"
00019 #include "G4Trap.hh"
00020 #include "G4Trd.hh"
00021 
00022 #include "G4LogicalVolume.hh"
00023 #include "G4ThreeVector.hh"
00024 #include "G4PVPlacement.hh"
00025 #include "G4UserLimits.hh"
00026 #include "globals.hh"
00027 
00028 #include "G4SDManager.hh"
00029 #include "G4VSensitiveDetector.hh"
00030 
00031 #include "G4UniformMagField.hh" 
00032 #include "G4EqMagElectricField.hh"
00033 #include "G4MagIntegratorStepper.hh"
00034 #include "G4Mag_UsualEqRhs.hh"
00035 #include "G4ChordFinder.hh"
00036 #include "G4PropagatorInField.hh"
00037 
00038 #include "G4UImanager.hh"
00039 #include "G4UIcommand.hh"
00040 
00041 #include "G4ios.hh"
00042 #include <iostream>
00043 
00044 // GDML export
00045 #include "G4GDMLParser.hh"
00046 
00047 //visual
00048 #include "G4VisAttributes.hh"
00049 #include "G4Colour.hh"
00050 
00051 
00052 
00053 MollerDetectorConstruction::MollerDetectorConstruction()
00054      :     
00055      Vacuum(0), Carbon(0), Al(0), Copper(0), Pb(0), Tungsten(0), 
00056      Iron(0), H(0), LH2(0),
00057      pGlobalMagnetField(0)
00058 {
00059 
00060   //Set the magnetic field here
00061   CreateGlobalMagneticField();
00062 
00063   detectorMessenger = new MollerDetectorMessenger(this);
00064   DefineMaterials();
00065   fTargetLength  = 150.0*cm;  
00066   collimfileName = "default_coll";
00067   NUM_COLS=10;
00068  
00069 }
00070 
00071 MollerDetectorConstruction::~MollerDetectorConstruction()
00072 {
00073   for (size_t i = 0; i < washer_logic.size(); i++)
00074     delete washer_logic[i];
00075   for (size_t i = 0; i < washer_phys.size(); i++)
00076     delete washer_phys[i];
00077 
00078   for (size_t i = 0; i < trapeziod_logic.size(); i++)
00079     delete trapeziod_logic[i];
00080   for (size_t i = 0; i < trapeziod_phys.size(); i++)
00081     delete trapeziod_phys[i];
00082 
00083   if (pGlobalMagnetField) delete pGlobalMagnetField;
00084   delete detectorMessenger;
00085 }
00086 
00087 void MollerDetectorConstruction::SetCollimGeomFile(const G4String& nam) 
00088 {
00089   collimfileName = nam;
00090 }
00091 void MollerDetectorConstruction::SetDetectorGeomFile(const G4String& nam) 
00092 {
00093   G4String fPath = ".";
00094   if (getenv("MOLLERGEANTDIR"))
00095     fPath = getenv("MOLLERGEANTDIR");
00096   else
00097     G4cout << "You do not have MOLLERGEANTDIR defined in your environment!" << G4endl;
00098 
00099   detfileName = (fPath+"/"+nam);
00100 }
00101 
00102 G4VPhysicalVolume*  MollerDetectorConstruction::Construct()
00103 {
00104 
00105   G4cout << G4endl << "###### Calling MollerDetectorConstruction::Read() " << G4endl << G4endl;
00106 
00107   if (fReadGeoFile){
00108 
00109     fGDMLParser.SetOverlapCheck(false);
00110     fGDMLParser.Read(detfileName);
00111 
00112     worldVolume = fGDMLParser.GetWorldVolume();
00113 
00114   //==========================
00115   // List auxiliary info
00116   //==========================
00117 
00118   const G4GDMLAuxMapType* auxmap = fGDMLParser.GetAuxMap();
00119 
00120   G4cout << "Found " << auxmap->size()
00121          << " volume(s) with auxiliary information."
00122          << G4endl << G4endl;
00123   for(G4GDMLAuxMapType::const_iterator
00124       iter  = auxmap->begin();
00125       iter != auxmap->end(); iter++) 
00126   {
00127     G4cout << "Volume " << ((*iter).first)->GetName()
00128            << " has the following list of auxiliary information: "<< G4endl;
00129     for (G4GDMLAuxListType::const_iterator
00130          vit  = (*iter).second.begin();
00131          vit != (*iter).second.end(); vit++)
00132     {
00133       G4cout << "--> Type: " << (*vit).type
00134              << " Value: "   << (*vit).value << std::endl;
00135     }
00136   }
00137   G4cout << G4endl<< G4endl;
00138 
00139 
00140   //==========================
00141   // Sensitive detectors
00142   //==========================
00143   G4SDManager* SDman = G4SDManager::GetSDMpointer();
00144   char detectorname[200];
00145 
00146   G4VSensitiveDetector* collimatordetector[100];
00147 
00148   G4int k=0;
00149   for(G4GDMLAuxMapType::const_iterator
00150       iter  = auxmap->begin();
00151       iter != auxmap->end(); iter++)
00152   {
00153     G4LogicalVolume* myvol = (*iter).first;
00154     G4cout << "Volume " << myvol->GetName();
00155     
00156     for (G4GDMLAuxListType::const_iterator
00157      vit  = (*iter).second.begin();
00158            vit != (*iter).second.end(); vit++)
00159     {
00160       if ((*vit).type == "SensDet")
00161       {
00162         G4String det_type = (*vit).value;
00163   //G4cout << " is a " << det_type <<  G4endl << G4endl;
00164 
00165   snprintf(detectorname,200,"/detector%i",k+1);
00166   collimatordetector[k] = new MollerDetectorSD(detectorname);
00167 
00168         if (collimatordetector[k] != 0)
00169         {
00170 
00171           G4cout << "  Creating sensitive detector " << det_type
00172                  << " for volume " << myvol->GetName()
00173                  <<  G4endl << G4endl;
00174 
00175           SDman->AddNewDetector(collimatordetector[k]);
00176           myvol->SetSensitiveDetector(collimatordetector[k]);
00177         }
00178         else
00179         {
00180           G4cout << det_type << " sensitive detector type not found" << G4endl;
00181   }
00182       }
00183     }
00184     k++;
00185   }
00186 
00187   //==========================
00188   // Visualization attributes
00189   //==========================
00190 
00191   G4VisAttributes* motherVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
00192   G4VisAttributes* daughterVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
00193   G4VisAttributes* targetVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,0.0));
00194   G4VisAttributes* planeDetVisAtt= new G4VisAttributes(G4Colour(0.3,0.8,0.5));
00195 
00196   motherVisAtt->SetVisibility(false);
00197 
00198   targetVisAtt->SetVisibility(true);
00199 
00200   daughterVisAtt->SetVisibility(true);
00201   daughterVisAtt->SetForceWireframe (true);
00202 
00203   planeDetVisAtt->SetVisibility(true);
00204   planeDetVisAtt->SetForceWireframe (true);
00205 
00206   G4VisAttributes* WVisAtt= new G4VisAttributes(G4Colour(0.7,0.7,0.7));
00207   G4VisAttributes* PbVisAtt= new G4VisAttributes(G4Colour(0.6,0.7,0.8));
00208   G4VisAttributes* CuVisAtt= new G4VisAttributes(G4Colour(1.0,0.5,0.1));
00209   G4VisAttributes* SiVisAtt= new G4VisAttributes(G4Colour(0.4,0.4,0.0));
00210 
00211   WVisAtt->SetVisibility(true);
00212   PbVisAtt->SetVisibility(true);
00213   CuVisAtt->SetVisibility(true);
00214   SiVisAtt->SetVisibility(true);
00215 
00216   worldVolume->GetLogicalVolume()->SetVisAttributes(motherVisAtt);
00217 
00218 
00219   for(int i=0;i<worldVolume->GetLogicalVolume()->GetNoDaughters();i++)
00220   {
00221 
00222     worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->SetVisAttributes(daughterVisAtt); 
00223 
00224     for (int j=0;j<worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetNoDaughters();j++) {
00225       worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->SetVisAttributes(daughterVisAtt);
00226 
00227     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->GetMaterial()->GetName().compare("VacuumDet")==0)
00228            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->SetVisAttributes(planeDetVisAtt); 
00229 
00230     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->GetMaterial()->GetName().compare("Tungsten")==0)
00231            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->SetVisAttributes(WVisAtt); 
00232 
00233     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->GetMaterial()->GetName().compare("Lead")==0)
00234            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->SetVisAttributes(PbVisAtt); 
00235 
00236     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->GetMaterial()->GetName().compare("Copper")==0)
00237            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->SetVisAttributes(CuVisAtt); 
00238 
00239     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->GetMaterial()->GetName().compare("SILICON")==0)
00240            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->SetVisAttributes(SiVisAtt); 
00241 
00242     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->GetMaterial()->GetName().compare("LiquidHydrogen")==0)
00243            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetDaughter(j)->GetLogicalVolume()->SetVisAttributes(targetVisAtt); 
00244     }
00245 
00246     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetMaterial()->GetName().compare("VacuumDet")==0)
00247            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->SetVisAttributes(planeDetVisAtt); 
00248 
00249     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetMaterial()->GetName().compare("Tungsten")==0)
00250            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->SetVisAttributes(WVisAtt); 
00251 
00252     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetMaterial()->GetName().compare("Lead")==0)
00253            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->SetVisAttributes(PbVisAtt); 
00254 
00255     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetMaterial()->GetName().compare("Copper")==0)
00256            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->SetVisAttributes(CuVisAtt); 
00257 
00258     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetMaterial()->GetName().compare("SILICON")==0)
00259            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->SetVisAttributes(SiVisAtt); 
00260 
00261     if (worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->GetMaterial()->GetName().compare("LiquidHydrogen")==0)
00262            worldVolume->GetLogicalVolume()->GetDaughter(i)->GetLogicalVolume()->SetVisAttributes(targetVisAtt); 
00263 
00264   }
00265 
00266   //target_logic->SetVisAttributes(targetVisAtt);
00267 
00268   // TODO
00269 
00270 
00271   //==========================
00272   // Output geometry tree
00273   //==========================
00274 
00275   G4cout << G4endl << "Element table: " << G4endl << G4endl;
00276   G4cout << *(G4Element::GetElementTable()) << G4endl;
00277 
00278   G4cout << G4endl << "Material table: " << G4endl << G4endl;
00279   G4cout << *(G4Material::GetMaterialTable()) << G4endl;
00280 
00281   G4cout << G4endl << "Geometry tree: " << G4endl << G4endl;
00282   DumpGeometricalTree(worldVolume);
00283 
00284   ReadGlobalMagneticField();
00285 
00286   } else {
00287 
00288     worldVolume = ConstructDetector();
00289   }
00290 
00291   G4cout << G4endl << "###### Leaving MollerDetectorConstruction::Read() " << G4endl << G4endl;
00292 
00293   return worldVolume;
00294 }
00295 
00296 void MollerDetectorConstruction::WriteGeometryFile(const G4String& filename)
00297 {
00298   G4bool appendPointerAddress = true;
00299   // Note: only change to false if all names are unique
00300   fGDMLParser.Write(filename,mother_phys,appendPointerAddress);
00301 }
00302 
00303 void MollerDetectorConstruction::DumpGeometricalTree(G4VPhysicalVolume* aVolume,G4int depth)
00304 {
00305   for(int isp=0;isp<depth;isp++)
00306   { G4cout << "  "; }
00307   G4cout << aVolume->GetName() << "[" << aVolume->GetCopyNo() << "] "
00308          << aVolume->GetLogicalVolume()->GetName() << " "
00309          << aVolume->GetLogicalVolume()->GetNoDaughters() << " "
00310          << aVolume->GetLogicalVolume()->GetMaterial()->GetName();
00311   if(aVolume->GetLogicalVolume()->GetSensitiveDetector())
00312   {
00313     G4cout << " " << aVolume->GetLogicalVolume()->GetSensitiveDetector()
00314                             ->GetFullPathName();
00315   }
00316   G4cout << G4endl;
00317   for(int i=0;i<aVolume->GetLogicalVolume()->GetNoDaughters();i++)
00318   { DumpGeometricalTree(aVolume->GetLogicalVolume()->GetDaughter(i),depth+1); }
00319 }
00320 
00321 void MollerDetectorConstruction::DefineMaterials()
00322 {
00323 
00324   //--------------------------------------------------------------//
00325   //-----------------------------MATERIALS------------------------//
00326   //--------------------------------------------------------------//
00327 
00328 
00329   G4double a;
00330   G4double z;
00331   G4double density;
00332   G4double temp = 20.27*kelvin;
00333   G4int natoms;
00334   G4int nComponents;
00335   G4String symbol;
00336 
00337   //-----VACUUM------//
00338 
00339   Vacuum = new G4Material("Vacuum", z=1., a=1.01*g/mole,
00340         density= universe_mean_density, 
00341         kStateGas, 2.73*kelvin, 3.e-18*pascal);
00342   
00343   //-----Carbon------//
00344   Carbon = new G4Material("Carbon", z= 6., a= 12.01*g/mole,
00345         density= 2.265*g/cm3);
00346 
00347   //-----Aluminum------//
00348   Al = new G4Material("Aluminum", z= 13., a= 26.98*g/mole,
00349           density= 2.7*g/cm3);
00350           
00351   //-----Copper------//
00352   Copper = new G4Material("Copper", z= 11., a= 63.54*g/mole,
00353         density= 8.96*g/cm3);
00354 
00355   //-----Lead------//
00356   Pb = new G4Material("Lead", z= 82., a= 207.19*g/mole, 
00357           density= 11.35*g/cm3);
00358   
00359   //-----Tungsten----//
00360   Tungsten = new G4Material("Tungsten", z= 74., a= 183.85*g/mole,
00361           density= 19.3*g/cm3);
00362   
00363   //-----Iron-----//
00364   Iron = new G4Material("Iron", z= 26., a= 55.85*g/mole,
00365       density= 7.87*g/cm3);
00366   
00367   //-----Liquid Hydrogen---//
00368   H  = new G4Element("Hydrogen", symbol="H", 
00369          z= 1., a= 1.00794*g/mole);
00370   LH2 = new G4Material("Liquid Hydrogen", density= 0.0708*g/cm3, 
00371             nComponents=1, kStateLiquid, temp);
00372 
00373   LH2->AddElement(H, natoms=1);
00374   
00375   
00376   // Print materials defined.
00377   G4cout << G4endl << "The materials defined are : " << G4endl << G4endl;
00378   G4cout << *(G4Material::GetMaterialTable()) << G4endl;
00379 
00380 }
00381 
00382 G4VPhysicalVolume* MollerDetectorConstruction::ConstructDetector()
00383 {
00384 
00385   G4SDManager* SDman = G4SDManager::GetSDMpointer();
00386   G4String SDname;
00387 
00388   G4VisAttributes* VacVisAtt= new G4VisAttributes(G4Colour(0.3,0.8,0.5));
00389   G4VisAttributes* WVisAtt= new G4VisAttributes(G4Colour(0.7,0.7,0.7));
00390   G4VisAttributes* PbVisAtt= new G4VisAttributes(G4Colour(0.6,0.7,0.8));
00391   G4VisAttributes* CuVisAtt= new G4VisAttributes(G4Colour(1.0,0.5,0.1));
00392 
00393   VacVisAtt->SetVisibility(true);
00394   VacVisAtt->SetForceWireframe (true);
00395 
00396   WVisAtt->SetVisibility(true);
00397   PbVisAtt->SetVisibility(true);
00398   CuVisAtt->SetVisibility(true);
00399 
00400   //--------------------------------------------------------------//
00401   //-----------------------------VOLUMES--------------------------//
00402   //--------------------------------------------------------------//
00403 
00404   G4double inner_rad = 0.0*cm;
00405   G4double start_angle = 0.0*deg;
00406   G4double end_angle = 360.0*deg;
00407   G4double half_side_mom = 200.0*cm;
00408   G4double half_len_mom = 4000.0*cm;
00409 
00410   G4double outer_rad_targ = 4.0*cm;
00411   G4double half_len_targ = fTargetLength/2;
00412 
00413   G4cout<< "target half-length = "<<half_len_targ/cm<<G4endl;
00414 
00415   G4UserLimits* userLimits = new G4UserLimits(1.0*cm);
00416 
00417   //------World-----//
00418 
00419   G4Box* mother_solid = new G4Box("boxMother", half_side_mom, half_side_mom,
00420            half_len_mom);
00421 
00422   mother_logic = new G4LogicalVolume(mother_solid, Vacuum, "logicMother", 0);
00423   mother_logic->SetUserLimits(userLimits);
00424 
00425   mother_phys = new G4PVPlacement(0,G4ThreeVector(), 
00426           mother_logic, "111", 
00427           0, false, 0);
00428 
00429 
00430   //------Target-----//
00431 
00432   target_solid = new G4Tubs("tubeTarget", inner_rad, outer_rad_targ,
00433            half_len_targ, start_angle, end_angle);
00434 
00435   target_logic = new G4LogicalVolume(target_solid, LH2, "logicTarget");
00436   //target_logic = new G4LogicalVolume(target_solid, Vacuum, "logicTarget"); //for optics plots
00437 
00438   target_phys = new G4PVPlacement(0,G4ThreeVector(0, 0, 0), 
00439           target_logic, "targ_0", 
00440           mother_logic , false, 0);
00441   //Visualization Attributes
00442   //
00443   G4VisAttributes* motherVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0));
00444   motherVisAtt->SetVisibility(false);
00445   mother_logic->SetVisAttributes(motherVisAtt);
00446 
00447   G4VisAttributes* targetVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,0.0));
00448   targetVisAtt->SetVisibility(true);
00449   target_logic->SetVisAttributes(targetVisAtt);
00450 
00451 
00452   //------Phi defining collimators
00453   const G4int numsectors=7;
00454   //  G4double startingphi=-pi/2;
00455   G4double startingphi=pi/2;
00456   G4double startingz=5.8*m;
00457   G4double radius=0.6*m;
00458   G4double internalholeradius=0*m;
00459   G4double thickness = 9.9*cm;
00460 
00461   G4VSensitiveDetector* collimatordetector[7];
00462 
00463   G4double openingangle=pi/numsectors;
00464   G4Trd* trapeziod_solid = new G4Trd("trapeziod_solid", 
00465              radius*tan(openingangle/2.),0.,thickness,thickness,(radius-internalholeradius)/2.);
00466   G4RotationMatrix rotmatrix[numsectors];
00467   char trapphysname[100], traplogname[100];
00468   char washphysname[100];
00469   char detectorname[200];
00470 
00471   for (G4int sector = 1; sector <= numsectors; sector++) {
00472     G4double phi = startingphi + 2.*(sector-1)*(pi/numsectors); 
00473     rotmatrix[sector-1].rotateX(pi/2.);
00474     rotmatrix[sector-1].rotateZ(-phi);
00475     G4double xpos = radius/2.*sin(phi);
00476     G4double ypos = radius/2.*cos(phi);
00477 
00478     snprintf(traplogname,100,"trapeziod_log_%i",sector);
00479     trapeziod_logic.push_back(new G4LogicalVolume(trapeziod_solid, Tungsten, traplogname));
00480 
00481 
00482     snprintf(trapphysname,100,"trap_phys_%i",sector+NUM_COLS);
00483     
00484 
00485     trapeziod_phys.push_back(
00486       new G4PVPlacement(G4Transform3D(rotmatrix[sector-1],
00487              G4ThreeVector(xpos,ypos,startingz)),
00488            //0,G4ThreeVector(xpos,ypos,startingz),
00489            trapeziod_logic.back(), 
00490            trapphysname, 
00491            mother_logic, 
00492            false, 
00493            0,
00494            false));
00495     snprintf(detectorname,200,"/detector%i",sector+NUM_COLS);
00496     collimatordetector[sector-1] = new MollerDetectorSD(SDname=detectorname);
00497     SDman->AddNewDetector(collimatordetector[sector-1]);
00498     trapeziod_logic.back()->SetSensitiveDetector(collimatordetector[sector-1]);
00499     trapeziod_logic.back()->SetVisAttributes(WVisAtt);
00500 
00501     
00502   }
00503 
00504 
00505   //-----3QC1B (center)-----// 
00506   //-----Washers----// 
00507 
00508   std::vector<G4VSensitiveDetector*> detector;
00509 
00510   // For E'=2.75 GeV, theta_lab=0.0167 rad which from z=0.75 m to z=5.9 m gives a radius of 11.1 cm.
00511   //For E'=8.25 GeV, theta_lab=0.00557 rad which from z=-0.75 m to z=5.9 m gives a radius of 5.15*tan(0.00557)= 2.86 cm
00512   
00513   //  G4double inrad[NUM_COLS], extrad[NUM_COLS], detzmin[NUM_COLS], detzmax[NUM_COLS], 
00514   std::vector<G4double> dethalfleng;
00515   std::vector<G4double> loc;
00516   dethalfleng.resize(NUM_COLS);
00517   loc.resize(NUM_COLS);
00518   //  G4VSolid* washer_solid[NUM_COLS];
00519 
00520   std::vector<G4VSolid*> washer_solid;
00521   washer_solid.resize(NUM_COLS);
00522 
00523   char washer_logicname[100];
00524 
00525   //G4String collgeofile=("$G4WORKDIR/geometry/"+collimfileName+".dat");
00526   G4String gPath = ".";
00527   if (getenv("MOLLERGEANTDIR"))
00528     gPath = getenv("MOLLERGEANTDIR");
00529   else
00530     G4cout << "You do not have MOLLERGEANTDIR defined in your environment!" << G4endl;
00531   G4String collgeofile=(gPath+"/geometry/"+collimfileName+".dat");
00532   ReadCollimatorGeometry(collgeofile);
00533 
00534   for (int i=0; i<NUM_COLS; i++) {
00535     loc[i] = (collUpstreamZ[i]+collDownstreamZ[i])/2;
00536     dethalfleng[i] = (collDownstreamZ[i]-collUpstreamZ[i])/2;
00537 
00538     washer_solid[i] = new G4Cons("solWasher"+
00539          G4UIcommand::ConvertToString((i+1)), 
00540          collInnerRadius[i], collOuterRadius[i],
00541          collInnerRadius[i], collOuterRadius[i], dethalfleng[i],
00542          start_angle, end_angle);
00543     
00544     snprintf(washer_logicname,100,"logicWasher_%i",i);
00545     snprintf(washphysname,100,"wash_phys_%i",i);    
00546 
00547     SDname = "/detector";
00548     SDname+=G4UIcommand::ConvertToString((i+1));
00549 
00550     detector.push_back (new MollerDetectorSD(SDname));
00551 
00552     SDman->AddNewDetector(detector[i]);
00553 
00554   
00555     if (collMaterial[i] == "Vacuum") {
00556       washer_logic.push_back(new G4LogicalVolume(washer_solid[i], Vacuum, washer_logicname, 0));
00557       washer_logic.back()->SetSensitiveDetector(detector[i]);
00558       washer_logic.back()->SetVisAttributes(VacVisAtt);
00559     } else if (collMaterial[i] == "Tungsten") {
00560       washer_logic.push_back(new G4LogicalVolume(washer_solid[i], Tungsten, washer_logicname, 0));
00561       washer_logic.back()->SetSensitiveDetector(detector[i]);
00562       washer_logic.back()->SetVisAttributes(WVisAtt);
00563      } else if (collMaterial[i] == "Lead") {
00564       washer_logic.push_back(new G4LogicalVolume(washer_solid[i], Pb, washer_logicname, 0));
00565       washer_logic.back()->SetSensitiveDetector(detector[i]);
00566       washer_logic.back()->SetVisAttributes(PbVisAtt);
00567     } else if (collMaterial[i] == "Copper") {
00568       washer_logic.push_back(new G4LogicalVolume(washer_solid[i], Copper, washer_logicname, 0));
00569       washer_logic.back()->SetSensitiveDetector(detector[i]);
00570       washer_logic.back()->SetVisAttributes(CuVisAtt);
00571      } else {
00572       G4cerr << G4endl<< " Check collimator "<< i <<" -  material not specified!" << G4endl;
00573       break;
00574     }
00575     
00576     
00577     washer_phys.push_back(new G4PVPlacement(0,G4ThreeVector(0, 0, loc[i]), 
00578                washer_logic.back(), 
00579                washphysname, 
00580                mother_logic, false, 0));
00581     
00582   }
00583   
00584 
00585   ReadGlobalMagneticField();
00586 
00587   return mother_phys;
00588 
00589 }
00590 
00591 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00592 void MollerDetectorConstruction::ReadGlobalMagneticField()
00593 {
00594   pGlobalMagnetField->ReadMagneticField();
00595 }
00596 
00597 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00598 void MollerDetectorConstruction::CreateGlobalMagneticField()   
00599 {
00600 
00601   //--------- Magnetic Field -------------------------------
00602   
00603   //============================================
00604   //  Define the global magnet field Manager
00605   //============================================
00606   pGlobalMagnetField = new MollerGlobalMagnetField();
00607 
00608   // Get transportation, field, and propagator  managers
00609   fGlobalFieldManager = G4TransportationManager::GetTransportationManager()->GetFieldManager();
00610   G4TransportationManager::GetTransportationManager()->GetPropagatorInField()->SetLargestAcceptableStep(25*cm);
00611   fGlobalFieldManager->SetDetectorField(pGlobalMagnetField);
00612   fGlobalEquation = new G4Mag_UsualEqRhs(pGlobalMagnetField);
00613   
00614   // taken from one of the Geant4 presentation:
00615   // - If the field is calculated from a field map, a lower order stepper
00616   //   is recommended: the less smooth the field is, the lower the order of the
00617   //   stepper that should be used. For very rough fields one should use 1st order
00618   //   stepper, for a somewhat smooth field one must choose between 1st and 2nd
00619   //   order stepper.
00620   
00621   //fGlobalStepper  = new G4ClassicalRK4(fGlobalEquation);  // classical 4th order stepper
00622   //fGlobalStepper  = new G4ExplicitEuler(fGlobalEquation); //           1st order stepper
00623   //fGlobalStepper  = new G4ImplicitEuler(fGlobalEquation); //           2nd order stepper
00624   fGlobalStepper  = new G4SimpleRunge(fGlobalEquation);   //           2nd order stepper
00625 
00626 
00627   // Provides a driver that talks to the Integrator Stepper, and insures that 
00628   //   the error is within acceptable bounds.
00629   G4MagInt_Driver* fGlobalIntgrDriver = new G4MagInt_Driver(1.0e-3*mm, 
00630                   fGlobalStepper,
00631                   fGlobalStepper->GetNumberOfVariables());
00632   
00633   fGlobalChordFinder = new G4ChordFinder(fGlobalIntgrDriver);
00634   
00635   
00636   
00637   //       G4bool fieldChangesEnergy = false;
00638   //       G4FieldManager* pFieldMgr = new G4FieldManager(myField,pChordFinder,FieldChangeEnergy);
00639   //       LocalLogicalVolume = new G4LogicalVolume(shape, material,"name",pFieldMgr,0,0);
00640   
00641   //   // minimal step of 1 mm is default
00642   //   fMinStep = 0.01*mm ;
00643   //
00644   //   fGlobalChordFinder = new G4ChordFinder (pGlobalMagnetField,
00645   //                                           fMinStep,
00646   //                                           fGlobalStepper);
00647   
00648   fGlobalFieldManager->SetChordFinder(fGlobalChordFinder);
00649 } 
00650 void MollerDetectorConstruction::ReadCollimatorGeometry(const char* filename)
00651 {
00652   
00653   G4cout << G4endl << "###### Calling MollerDetectorConstruction::ReadCollimatorGeometry " << G4endl << G4endl;
00654   //G4cout << G4endl;
00655   //G4cout << "------------------------------------------------" << G4endl;
00656   //G4cout << " Getting collimator geometry from " << filename   << G4endl; 
00657   //G4cout << "------------------------------------------------" << G4endl;
00658 
00659 
00660   G4int   coll_index=0;
00661   G4double ri,ro,zu,zd;
00662   G4String collmat;
00663 
00664   // open the collimator geometry file
00665   std::ifstream inputfile;
00666   inputfile.open(filename); // Open the file for reading.
00667   G4cout << G4endl << filename << " opened for reading, ncolls =" <<NUM_COLS<< G4endl<< G4endl;
00668 
00669   for (G4int nlines=0;nlines<NUM_COLS;nlines++) {
00670 
00671     if (!inputfile.good()) break;
00672 
00673     inputfile >> ri  >> ro >> zu >> zd >> collmat; 
00674 
00675     //printf("coll ri ro zu zd: %2i  %f %f %f %f %s\n",coll_index, ri, ro, zu, zd, collmat.c_str());
00676 
00677     collInnerRadius.push_back (ri*cm);
00678     collOuterRadius.push_back (ro*cm);
00679     collUpstreamZ.push_back (zu*cm);
00680     collDownstreamZ.push_back (zd*cm);
00681     collMaterial.push_back (collmat);
00682 
00683     printf("coll ri ro zu zd: %2i  %7.2f %7.2f %7.2f %7.2f \t %s\n",coll_index, collInnerRadius[nlines]/cm, collOuterRadius[nlines]/cm, 
00684      collUpstreamZ[nlines]/cm, collDownstreamZ[nlines]/cm, collMaterial[nlines].c_str());
00685     //printf("coll ri ro zu zd: %2i  %f %f %f %f %s\n",coll_index, collInnerRadius[nlines], collOuterRadius[nlines], 
00686     //   collUpstreamZ[nlines], collDownstreamZ[nlines], collMaterial[nlines]->GetName());
00687     coll_index++;
00688   }
00689 
00690   
00691   // close file
00692   inputfile.close();
00693   
00694   if (coll_index!=NUM_COLS) {
00695     G4cerr <<"coll_index, "<< coll_index<<" not equal to NUM_COLS,"<<NUM_COLS<<G4endl;
00696   }
00697   else if ((int)collDownstreamZ.size()!=NUM_COLS) {
00698     G4cerr <<"collDownstreamZ.size(), "<< collDownstreamZ.size()<<" not equal to NUM_COLS, "<<NUM_COLS<<G4endl;
00699   }
00700   G4cout << "... done reading " << coll_index << " lines." << G4endl;
00701   
00702   G4cout << G4endl << "###### Leaving MollerDetectorConstruction::ReadCollimatorGeometry " << G4endl << G4endl;
00703 }

Generated on 16 Jun 2013 for mollersim by  doxygen 1.6.1