Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // >> 26 // $Id$ 26 // 27 // 27 /// \file B2bDetectorConstruction.cc 28 /// \file B2bDetectorConstruction.cc 28 /// \brief Implementation of the B2bDetectorCo 29 /// \brief Implementation of the B2bDetectorConstruction class 29 << 30 30 #include "B2bDetectorConstruction.hh" 31 #include "B2bDetectorConstruction.hh" 31 << 32 #include "B2TrackerSD.hh" << 33 #include "B2bChamberParameterisation.hh" << 34 #include "B2bDetectorMessenger.hh" 32 #include "B2bDetectorMessenger.hh" >> 33 #include "B2bChamberParameterisation.hh" >> 34 #include "B2TrackerSD.hh" 35 35 36 #include "G4Box.hh" << 37 #include "G4Colour.hh" << 38 #include "G4GeometryManager.hh" << 39 #include "G4GeometryTolerance.hh" << 40 #include "G4GlobalMagFieldMessenger.hh" << 41 #include "G4LogicalVolume.hh" << 42 #include "G4Material.hh" 36 #include "G4Material.hh" 43 #include "G4NistManager.hh" 37 #include "G4NistManager.hh" 44 #include "G4PVParameterised.hh" << 38 >> 39 #include "G4Box.hh" >> 40 #include "G4Tubs.hh" >> 41 #include "G4LogicalVolume.hh" 45 #include "G4PVPlacement.hh" 42 #include "G4PVPlacement.hh" >> 43 #include "G4PVParameterised.hh" >> 44 #include "G4GlobalMagFieldMessenger.hh" 46 #include "G4SDManager.hh" 45 #include "G4SDManager.hh" 47 #include "G4SystemOfUnits.hh" << 46 48 #include "G4Tubs.hh" << 47 #include "G4GeometryTolerance.hh" >> 48 #include "G4GeometryManager.hh" >> 49 49 #include "G4UserLimits.hh" 50 #include "G4UserLimits.hh" >> 51 50 #include "G4VisAttributes.hh" 52 #include "G4VisAttributes.hh" >> 53 #include "G4Colour.hh" >> 54 >> 55 #include "G4SystemOfUnits.hh" 51 56 52 // #include "G4ios.hh" << 57 //#include "G4ios.hh" 53 58 54 //....oooOO0OOooo........oooOO0OOooo........oo 59 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 55 60 56 G4ThreadLocal G4GlobalMagFieldMessenger* B2bDe << 61 G4ThreadLocal 57 << 62 G4GlobalMagFieldMessenger* B2bDetectorConstruction::fMagFieldMessenger = 0; >> 63 58 B2bDetectorConstruction::B2bDetectorConstructi 64 B2bDetectorConstruction::B2bDetectorConstruction() 59 : G4VUserDetectorConstruction(), << 65 :G4VUserDetectorConstruction(), 60 fLogicTarget(NULL), << 66 fLogicTarget(NULL), fLogicChamber(NULL), 61 fLogicChamber(NULL), << 67 fTargetMaterial(NULL), fChamberMaterial(NULL), 62 fTargetMaterial(NULL), << 68 fStepLimit(NULL), 63 fChamberMaterial(NULL), << 69 fCheckOverlaps(true) 64 fStepLimit(NULL), << 65 fCheckOverlaps(true) << 66 { 70 { 67 fMessenger = new B2bDetectorMessenger(this); 71 fMessenger = new B2bDetectorMessenger(this); 68 } 72 } 69 73 70 //....oooOO0OOooo........oooOO0OOooo........oo 74 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 71 << 75 72 B2bDetectorConstruction::~B2bDetectorConstruct 76 B2bDetectorConstruction::~B2bDetectorConstruction() 73 { 77 { 74 delete fStepLimit; 78 delete fStepLimit; 75 delete fMessenger; 79 delete fMessenger; 76 delete fMagFieldMessenger; 80 delete fMagFieldMessenger; 77 fMagFieldMessenger = 0; 81 fMagFieldMessenger = 0; 78 } 82 } 79 83 80 //....oooOO0OOooo........oooOO0OOooo........oo 84 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 81 << 85 82 G4VPhysicalVolume* B2bDetectorConstruction::Co 86 G4VPhysicalVolume* B2bDetectorConstruction::Construct() 83 { 87 { 84 // Define materials 88 // Define materials 85 DefineMaterials(); 89 DefineMaterials(); 86 90 87 // Define volumes 91 // Define volumes 88 return DefineVolumes(); 92 return DefineVolumes(); 89 } 93 } 90 94 91 //....oooOO0OOooo........oooOO0OOooo........oo 95 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 92 96 93 void B2bDetectorConstruction::DefineMaterials( 97 void B2bDetectorConstruction::DefineMaterials() 94 { 98 { 95 // Material definition << 99 // Material definition 96 100 97 G4NistManager* nistManager = G4NistManager:: 101 G4NistManager* nistManager = G4NistManager::Instance(); 98 102 99 // Air defined using NIST Manager 103 // Air defined using NIST Manager 100 nistManager->FindOrBuildMaterial("G4_AIR"); 104 nistManager->FindOrBuildMaterial("G4_AIR"); 101 << 105 102 // Lead defined using NIST Manager 106 // Lead defined using NIST Manager 103 fTargetMaterial = nistManager->FindOrBuildMa << 107 fTargetMaterial = nistManager->FindOrBuildMaterial("G4_Pb"); 104 108 105 // Xenon gas defined using NIST Manager 109 // Xenon gas defined using NIST Manager 106 fChamberMaterial = nistManager->FindOrBuildM 110 fChamberMaterial = nistManager->FindOrBuildMaterial("G4_Xe"); 107 111 108 // Print materials 112 // Print materials 109 G4cout << *(G4Material::GetMaterialTable()) 113 G4cout << *(G4Material::GetMaterialTable()) << G4endl; 110 } 114 } 111 115 112 //....oooOO0OOooo........oooOO0OOooo........oo 116 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 113 117 114 G4VPhysicalVolume* B2bDetectorConstruction::De 118 G4VPhysicalVolume* B2bDetectorConstruction::DefineVolumes() 115 { 119 { 116 G4Material* air = G4Material::GetMaterial("G << 120 G4Material* air = G4Material::GetMaterial("G4_AIR"); 117 121 118 // Sizes of the principal geometrical compon 122 // Sizes of the principal geometrical components (solids) 119 << 123 120 G4int NbOfChambers = 5; 124 G4int NbOfChambers = 5; 121 G4double chamberSpacing = 80 * cm; // from << 125 G4double chamberSpacing = 80*cm; // from chamber center to center! 122 << 123 G4double chamberWidth = 20.0 * cm; // width << 124 G4double targetLength = 5.0 * cm; // full l << 125 << 126 G4double trackerLength = (NbOfChambers + 1) << 127 << 128 G4double worldLength = 1.2 * (2 * targetLeng << 129 126 130 G4double targetRadius = 0.5 * targetLength; << 127 G4double chamberWidth = 20.0*cm; // width of the chambers 131 targetLength = 0.5 * targetLength; // Half << 128 G4double targetLength = 5.0*cm; // full length of Target 132 G4double trackerSize = 0.5 * trackerLength; << 129 >> 130 G4double trackerLength = (NbOfChambers+1)*chamberSpacing; >> 131 >> 132 G4double worldLength = 1.2 * (2*targetLength + trackerLength); >> 133 >> 134 G4double targetRadius = 0.5*targetLength; // Radius of Target >> 135 targetLength = 0.5*targetLength; // Half length of the Target >> 136 G4double trackerSize = 0.5*trackerLength; // Half length of the Tracker 133 137 134 // Definitions of Solids, Logical Volumes, P 138 // Definitions of Solids, Logical Volumes, Physical Volumes 135 139 136 // World 140 // World 137 141 138 G4GeometryManager::GetInstance()->SetWorldMa 142 G4GeometryManager::GetInstance()->SetWorldMaximumExtent(worldLength); 139 143 140 G4cout << "Computed tolerance = " 144 G4cout << "Computed tolerance = " 141 << G4GeometryTolerance::GetInstance() << 145 << G4GeometryTolerance::GetInstance()->GetSurfaceTolerance()/mm 142 << 146 << " mm" << G4endl; 143 G4Box* worldS = new G4Box("world", // its n << 144 worldLength / 2, w << 145 G4LogicalVolume* worldLV = new G4LogicalVolu << 146 << 147 << 148 147 >> 148 G4Box* worldS >> 149 = new G4Box("world", //its name >> 150 worldLength/2,worldLength/2,worldLength/2); //its size >> 151 G4LogicalVolume* worldLV >> 152 = new G4LogicalVolume( >> 153 worldS, //its solid >> 154 air, //its material >> 155 "World"); //its name >> 156 149 // Must place the World Physical volume unr 157 // Must place the World Physical volume unrotated at (0,0,0). 150 // << 158 // 151 G4VPhysicalVolume* worldPV = new G4PVPlaceme << 159 G4VPhysicalVolume* worldPV 152 << 160 = new G4PVPlacement( 153 << 161 0, // no rotation 154 << 162 G4ThreeVector(), // at (0,0,0) 155 << 163 worldLV, // its logical volume 156 << 164 "World", // its name 157 << 165 0, // its mother volume 158 << 166 false, // no boolean operations >> 167 0, // copy number >> 168 fCheckOverlaps); // checking overlaps 159 169 160 // Target 170 // Target >> 171 >> 172 G4ThreeVector positionTarget = G4ThreeVector(0,0,-(targetLength+trackerSize)); 161 173 162 G4ThreeVector positionTarget = G4ThreeVector << 174 G4Tubs* targetS 163 << 175 = new G4Tubs("target",0.,targetRadius,targetLength,0.*deg,360.*deg); 164 G4Tubs* targetS = new G4Tubs("target", 0., t << 176 fLogicTarget 165 fLogicTarget = new G4LogicalVolume(targetS, << 177 = new G4LogicalVolume(targetS, fTargetMaterial,"Target",0,0,0); 166 new G4PVPlacement(0, // no rotation << 178 new G4PVPlacement(0, // no rotation 167 positionTarget, // at (x, << 179 positionTarget, // at (x,y,z) 168 fLogicTarget, // its logi << 180 fLogicTarget, // its logical volume 169 "Target", // its name << 181 "Target", // its name 170 worldLV, // its mother vo << 182 worldLV, // its mother volume 171 false, // no boolean oper << 183 false, // no boolean operations 172 0, // copy number << 184 0, // copy number 173 fCheckOverlaps); // check << 185 fCheckOverlaps); // checking overlaps 174 186 175 G4cout << "Target is " << 2 * targetLength / << 187 G4cout << "Target is " << 2*targetLength/cm << " cm of " 176 << G4endl; << 188 << fTargetMaterial->GetName() << G4endl; 177 189 178 // Tracker 190 // Tracker >> 191 >> 192 G4ThreeVector positionTracker = G4ThreeVector(0,0,0); 179 193 180 G4ThreeVector positionTracker = G4ThreeVecto << 194 G4Tubs* trackerS 181 << 195 = new G4Tubs("tracker",0,trackerSize,trackerSize, 0.*deg, 360.*deg); 182 G4Tubs* trackerS = new G4Tubs("tracker", 0, << 196 G4LogicalVolume* trackerLV 183 G4LogicalVolume* trackerLV = new G4LogicalVo << 197 = new G4LogicalVolume(trackerS, air, "Tracker",0,0,0); 184 new G4PVPlacement(0, // no rotation << 198 new G4PVPlacement(0, // no rotation 185 positionTracker, // at (x << 199 positionTracker, // at (x,y,z) 186 trackerLV, // its logical << 200 trackerLV, // its logical volume 187 "Tracker", // its name << 201 "Tracker", // its name 188 worldLV, // its mother v << 202 worldLV, // its mother volume 189 false, // no boolean oper << 203 false, // no boolean operations 190 0, // copy number << 204 0, // copy number 191 fCheckOverlaps); // check << 205 fCheckOverlaps); // checking overlaps 192 206 193 // Tracker segments 207 // Tracker segments 194 << 208 195 // An example of Parameterised volumes 209 // An example of Parameterised volumes 196 // Dummy values for G4Tubs -- modified by pa 210 // Dummy values for G4Tubs -- modified by parameterised volume 197 211 198 G4Tubs* chamberS = new G4Tubs("tracker", 0, << 212 G4Tubs* chamberS 199 fLogicChamber = new G4LogicalVolume(chamberS << 213 = new G4Tubs("tracker",0, 100*cm, 100*cm, 0.*deg, 360.*deg); 200 << 214 fLogicChamber >> 215 = new G4LogicalVolume(chamberS,fChamberMaterial,"Chamber",0,0,0); >> 216 201 G4double firstPosition = -trackerSize + cham 217 G4double firstPosition = -trackerSize + chamberSpacing; 202 G4double firstLength = trackerLength / 10; << 218 G4double firstLength = trackerLength/10; 203 G4double lastLength = trackerLength; << 219 G4double lastLength = trackerLength; 204 220 205 G4VPVParameterisation* chamberParam = 221 G4VPVParameterisation* chamberParam = 206 new B2bChamberParameterisation(NbOfChamber << 222 new B2bChamberParameterisation( 207 firstPositi << 223 NbOfChambers, // NoChambers 208 chamberSpac << 224 firstPosition, // Z of center of first 209 chamberWidt << 225 chamberSpacing, // Z spacing of centers 210 firstLength << 226 chamberWidth, // chamber width 211 lastLength) << 227 firstLength, // initial length 212 << 228 lastLength); // final length >> 229 213 // dummy value : kZAxis -- modified by param 230 // dummy value : kZAxis -- modified by parameterised volume 214 231 215 new G4PVParameterised("Chamber", // their n << 232 new G4PVParameterised("Chamber", // their name 216 fLogicChamber, // the << 233 fLogicChamber, // their logical volume 217 trackerLV, // Mother << 234 trackerLV, // Mother logical volume 218 kZAxis, // Are placed << 235 kZAxis, // Are placed along this axis 219 NbOfChambers, // Numb << 236 NbOfChambers, // Number of chambers 220 chamberParam, // The << 237 chamberParam, // The parametrisation 221 fCheckOverlaps); // c << 238 fCheckOverlaps); // checking overlaps 222 239 223 G4cout << "There are " << NbOfChambers << " 240 G4cout << "There are " << NbOfChambers << " chambers in the tracker region. " 224 << "\nThe chambers are " << chamberWi << 241 << "\nThe chambers are " << chamberWidth/cm << " cm of " 225 << "\nThe distance between chamber is << 242 << fChamberMaterial->GetName() << "\nThe distance between chamber is " >> 243 << chamberSpacing/cm << " cm" << G4endl; 226 244 227 // Visualization attributes 245 // Visualization attributes 228 246 229 G4VisAttributes* boxVisAtt = new G4VisAttrib << 247 G4VisAttributes* boxVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0)); 230 worldLV->SetVisAttributes(boxVisAtt); << 248 worldLV ->SetVisAttributes(boxVisAtt); 231 fLogicTarget->SetVisAttributes(boxVisAtt); << 249 fLogicTarget ->SetVisAttributes(boxVisAtt); 232 trackerLV->SetVisAttributes(boxVisAtt); << 250 trackerLV ->SetVisAttributes(boxVisAtt); 233 251 234 G4VisAttributes* chamberVisAtt = new G4VisAt << 252 G4VisAttributes* chamberVisAtt = new G4VisAttributes(G4Colour(1.0,1.0,0.0)); 235 fLogicChamber->SetVisAttributes(chamberVisAt 253 fLogicChamber->SetVisAttributes(chamberVisAtt); 236 << 254 237 // Example of User Limits 255 // Example of User Limits 238 // 256 // 239 // Below is an example of how to set trackin 257 // Below is an example of how to set tracking constraints in a given 240 // logical volume 258 // logical volume 241 // 259 // 242 // Sets a max step length in the tracker reg 260 // Sets a max step length in the tracker region, with G4StepLimiter 243 261 244 G4double maxStep = 0.5 * chamberWidth; << 262 G4double maxStep = 0.5*chamberWidth; 245 fStepLimit = new G4UserLimits(maxStep); 263 fStepLimit = new G4UserLimits(maxStep); 246 trackerLV->SetUserLimits(fStepLimit); 264 trackerLV->SetUserLimits(fStepLimit); 247 << 265 248 /// Set additional contraints on the track, 266 /// Set additional contraints on the track, with G4UserSpecialCuts 249 /// 267 /// 250 /// G4double maxLength = 2*trackerLength, ma 268 /// G4double maxLength = 2*trackerLength, maxTime = 0.1*ns, minEkin = 10*MeV; 251 /// trackerLV->SetUserLimits(new G4UserLimit 269 /// trackerLV->SetUserLimits(new G4UserLimits(maxStep, 252 /// 270 /// maxLength, 253 /// 271 /// maxTime, 254 /// 272 /// minEkin)); 255 273 256 // Always return the physical world 274 // Always return the physical world 257 275 258 return worldPV; 276 return worldPV; 259 } 277 } 260 278 261 //....oooOO0OOooo........oooOO0OOooo........oo 279 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 262 << 280 263 void B2bDetectorConstruction::ConstructSDandFi 281 void B2bDetectorConstruction::ConstructSDandField() 264 { 282 { 265 // Sensitive detectors 283 // Sensitive detectors 266 284 267 G4String trackerChamberSDname = "B2/TrackerC 285 G4String trackerChamberSDname = "B2/TrackerChamberSD"; 268 B2TrackerSD* aTrackerSD = new B2TrackerSD(tr << 286 B2TrackerSD* aTrackerSD = new B2TrackerSD(trackerChamberSDname, >> 287 "TrackerHitsCollection"); 269 G4SDManager::GetSDMpointer()->AddNewDetector 288 G4SDManager::GetSDMpointer()->AddNewDetector(aTrackerSD); 270 SetSensitiveDetector(fLogicChamber, aTracker << 289 SetSensitiveDetector( fLogicChamber, aTrackerSD ); 271 290 272 // Create global magnetic field messenger. 291 // Create global magnetic field messenger. 273 // Uniform magnetic field is then created au 292 // Uniform magnetic field is then created automatically if 274 // the field value is not zero. 293 // the field value is not zero. 275 G4ThreeVector fieldValue = G4ThreeVector(); 294 G4ThreeVector fieldValue = G4ThreeVector(); 276 fMagFieldMessenger = new G4GlobalMagFieldMes 295 fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue); 277 fMagFieldMessenger->SetVerboseLevel(1); 296 fMagFieldMessenger->SetVerboseLevel(1); 278 } 297 } 279 298 280 //....oooOO0OOooo........oooOO0OOooo........oo 299 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 281 300 282 void B2bDetectorConstruction::SetTargetMateria 301 void B2bDetectorConstruction::SetTargetMaterial(G4String materialName) 283 { 302 { 284 G4NistManager* nistManager = G4NistManager:: 303 G4NistManager* nistManager = G4NistManager::Instance(); 285 304 286 G4Material* pttoMaterial = nistManager->Find << 305 G4Material* pttoMaterial = >> 306 nistManager->FindOrBuildMaterial(materialName); 287 307 288 if (fTargetMaterial != pttoMaterial) { 308 if (fTargetMaterial != pttoMaterial) { 289 if (pttoMaterial) { << 309 if ( pttoMaterial ) { 290 fTargetMaterial = pttoMaterial; << 310 fTargetMaterial = pttoMaterial; 291 if (fLogicTarget) fLogicTarget->SetMater << 311 if (fLogicTarget) fLogicTarget->SetMaterial(fTargetMaterial); 292 G4cout << "\n----> The target is made of << 312 G4cout << "\n----> The target is made of " << materialName << G4endl; 293 } << 313 } else { 294 else { << 314 G4cout << "\n--> WARNING from SetTargetMaterial : " 295 G4cout << "\n--> WARNING from SetTarget << 315 << materialName << " not found" << G4endl; 296 << G4endl; << 316 } 297 } << 298 } 317 } 299 } 318 } 300 << 319 301 //....oooOO0OOooo........oooOO0OOooo........oo 320 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 302 321 303 void B2bDetectorConstruction::SetChamberMateri 322 void B2bDetectorConstruction::SetChamberMaterial(G4String materialName) 304 { 323 { 305 G4NistManager* nistManager = G4NistManager:: 324 G4NistManager* nistManager = G4NistManager::Instance(); 306 325 307 G4Material* pttoMaterial = nistManager->Find << 326 G4Material* pttoMaterial = >> 327 nistManager->FindOrBuildMaterial(materialName); 308 328 309 if (fChamberMaterial != pttoMaterial) { 329 if (fChamberMaterial != pttoMaterial) { 310 if (pttoMaterial) { << 330 if ( pttoMaterial ) { 311 fChamberMaterial = pttoMaterial; << 331 fChamberMaterial = pttoMaterial; 312 if (fLogicChamber) fLogicChamber->SetMat << 332 if (fLogicChamber) fLogicChamber->SetMaterial(fChamberMaterial); 313 G4cout << "\n----> The chambers are made << 333 G4cout << "\n----> The chambers are made of " << materialName << G4endl; 314 } << 334 } else { 315 else { << 335 G4cout << "\n--> WARNING from SetChamberMaterial : " 316 G4cout << "\n--> WARNING from SetChambe << 336 << materialName << " not found" << G4endl; 317 << G4endl; << 337 } 318 } << 319 } 338 } 320 } 339 } 321 340 322 //....oooOO0OOooo........oooOO0OOooo........oo 341 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 323 << 342 324 void B2bDetectorConstruction::SetMaxStep(G4dou 343 void B2bDetectorConstruction::SetMaxStep(G4double maxStep) 325 { 344 { 326 if ((fStepLimit) && (maxStep > 0.)) fStepLim << 345 if ((fStepLimit)&&(maxStep>0.)) fStepLimit->SetMaxAllowedStep(maxStep); 327 } 346 } 328 347 329 //....oooOO0OOooo........oooOO0OOooo........oo 348 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 330 349