/***************************************************************************
 *  musrSim - the program for the simulation of (mainly) muSR instruments. *
 *          More info on http://lmu.web.psi.ch/simulation/index.html .     *
 *          musrSim is based od Geant4 (http://geant4.web.cern.ch/geant4/) *
 *                                                                         *
 *  Copyright (C) 2009 by Paul Scherrer Institut, 5232 Villigen PSI,       *
 *                                                       Switzerland       *
 *                                                                         *
 *  This program is free software; you can redistribute it and/or modify   *
 *  it under the terms of the GNU General Public License as published by   *
 *  the Free Software Foundation; either version 2 of the License, or      *
 *  (at your option) any later version.                                    *
 *                                                                         *
 *  This program is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
 *  GNU General Public License for more details.                           *
 *                                                                         *
 *  You should have received a copy of the GNU General Public License      *
 *  along with this program; if not, write to the Free Software            *
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              *
 ***************************************************************************/

#include "musrDetectorConstruction.hh"
#include "musrDetectorMessenger.hh"
#include "musrTabulatedElementField.hh"
#include "musrQuadrupole.hh"
#include "musrUniformField.hh"             // Uniform EM field (B,E) implemented by Toni Shiroka

#include "musrScintSD.hh"
#include "musrEventAction.hh"

#include "G4GeometryManager.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4SolidStore.hh"
#include "G4SDManager.hh"
#include "G4PVParameterised.hh"
#include "G4UnionSolid.hh"
#include "G4IntersectionSolid.hh"
#include "G4SubtractionSolid.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4Box.hh"
#include "G4Cons.hh"
#include "G4Polycone.hh"
#include "G4Torus.hh"
#include "G4LogicalVolume.hh"
#include "G4PVPlacement.hh"
#include "G4Tubs.hh"
#include "G4Sphere.hh"
#include "G4Trd.hh"
#include "G4Para.hh"
#include "G4PVDivision.hh"
#include "G4UserLimits.hh"

// In order to implement overlaping field as was done by 
// Gumplinger in examples/extended/field/field04/
#include "F04GlobalField.hh"

#include "G4VisAttributes.hh"
#include "G4Colour.hh"
#include "G4ios.hh"

#include "G4Region.hh"
#include "G4RegionStore.hh"
#include "G4ProductionCuts.hh"

//#include "G4OpticalSurface.hh"
#include "G4LogicalBorderSurface.hh"

#include "musrRootOutput.hh"   //cks for storing some info in the Root output file
#include "musrParameters.hh"
#include "musrErrorMessage.hh"
#include "musrSteppingAction.hh"

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

musrDetectorConstruction::musrDetectorConstruction(G4String steeringFileName)
:checkOverlap(true), aScintSD(0)
{  
  parameterFileName = steeringFileName;
  DefineMaterials();
  detectorMessenger = new musrDetectorMessenger(this);
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 
musrDetectorConstruction::~musrDetectorConstruction()
{
  delete detectorMessenger;             
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

#include "G4LogicalVolumeStore.hh"
G4VPhysicalVolume* musrDetectorConstruction::Construct()  {
  // Clean old geometry, if any
  //
  G4GeometryManager::GetInstance()->OpenGeometry();
  G4PhysicalVolumeStore::GetInstance()->Clean();
  G4LogicalVolumeStore::GetInstance()->Clean();
  G4SolidStore::GetInstance()->Clean();

  //  G4cout<< "musrDetectorConstruction::Construct:  ParameterFileName="<<parameterFileName<<G4endl;

  //  G4double roundingErr=0.001*mm;     
  //  G4double roundingErr=0.01*mm;        // 0.01mm precision is OK for displaying subtracted volumes, while 0.001mm is not
  //----------------------

  musrRootOutput*     myRootOutput     = musrRootOutput::GetRootInstance();
  musrSteppingAction* mySteppingAction = musrSteppingAction::GetInstance();


  G4VPhysicalVolume* pointerToWorldVolume=NULL;
  //  Read detector configuration parameters from the steering file:
  FILE *fSteeringFile=fopen(parameterFileName.c_str(),"r");
  if (fSteeringFile==NULL) {
    if (parameterFileName=="Unset") {
      G4cout<<"musrDetectorConstruction:  No input macro file specified"<<G4endl;
    }
    else {
      G4cout << "E R R O R :    Failed to open detector configuration file " << parameterFileName << G4endl;
    }
    G4cout << "S T O P    F O R C E D" << G4endl;
    exit(1);
  }
  G4cout << "Detector configuration file \"" << parameterFileName << "\" was opened."<<G4endl;
  char  line[501];

  // Write out the configuration file into the output file:
  G4cout << "\n\n....oooOO0OOooo........oooOO0OOooo......Configuration file used for this run....oooOO0OOooo........oooOO0OOooo......"<<G4endl; 
  while (!feof(fSteeringFile)) {
    fgets(line,500,fSteeringFile);
    //    if ((line[0]!='#')&&(line[0]!='\n')&&(line[0]!='\r'))  // TS: Do not print comments
    G4cout << line;
  }
  G4cout <<"....oooOO0OOooo........oooOO0OOooo......End of the configuration file.....oooOO0OOooo........oooOO0OOooo......\n\n"<<G4endl;

  // Loop
  rewind (fSteeringFile);
  char eMessage[200];
  while (!feof(fSteeringFile)) {
    fgets(line,500,fSteeringFile);
    //    if (line[0]!='*') {
    if ((line[0]!='#')&&(line[0]!='\n')&&(line[0]!='\r')) {
      char tmpString0[100]="Unset";
      sscanf(&line[0],"%s",tmpString0);
      if ( (strcmp(tmpString0,"/musr/ignore")!=0) &&(strcmp(tmpString0,"/musr/command")!=0) ) continue;
      

      char tmpString1[100]="Unset",tmpString2[100]="Unset",tmpString3[100]="Unset";
      sscanf(&line[0],"%*s %s %s",tmpString1,tmpString2);

      // Define rotation matrix, which might be later on used for some volumes
      if (strcmp(tmpString1,"rotation")==0){
	char matrixName[100]="Unset";
	double pp1, pp2, pp3, pp4=0;
	sscanf(&line[0],"%*s %*s %s %lf %lf %lf %lf",matrixName,&pp1,&pp2,&pp3,&pp4);
	if (pp4==0) {
	  G4RotationMatrix* pRotMatrix = new G4RotationMatrix(pp1*deg,pp2*deg,pp3*deg);  // pp1=phi, pp2=theta, pp3=psi
	  pointerToRotationMatrix[matrixName]=pRotMatrix;
	}
	else {
	  G4RotationMatrix* pRotMatrix = new G4RotationMatrix(G4ThreeVector(pp1,pp2,pp3),pp4*deg);
	  pointerToRotationMatrix[matrixName]=pRotMatrix;
	}
      }

      // Define array, which is needed for G4Polycone definition
      else if (strcmp(tmpString1,"arrayDef")==0){
	const int maxArrayLength=100;
	double* newArray = new double[maxArrayLength];
	char arrayName[100]="Unset";
	int  nValues;
        sscanf(&line[0],"%*s %*s %s %d",arrayName,&nValues);
	if (nValues>maxArrayLength) {
	  G4cout<<"musrDetectorConstruction: arrayDef: currently the array can not have more than "<<maxArrayLength<<" elements."<<G4endl;
	  G4cout<<"      Please either increse the \"maxArrayLength\" variable in musrDetectorConstruction.cc or use shorter arrays."<<G4endl;
	  G4cout << "S T O P    F O R C E D"<<G4endl;
	  G4cout<<"   "<<line<<G4endl;
	  exit(1);
	}
	else {
	  char NAME1[100];
	  double pp1;
	  char* pch = strstr(line,arrayName)+strlen(arrayName);
	  for (int iji=0; iji<nValues; iji++) {
	    sscanf(pch,"%s",NAME1);
	    char *pch1 = strstr(pch,NAME1)+strlen(NAME1);
	    pch=pch1;
	    sscanf(pch,"%lf",&pp1);
	    newArray[iji]=pp1;
	  }
	}
	G4cout<<"New array defined: "<<arrayName<<"=(";
	for (int iji=0; iji<nValues; iji++) {
	  G4cout<<newArray[iji]; 
	  if (iji<nValues-1) {G4cout<<",";}
	  else             {G4cout<<")";}
	}
	G4cout<<G4endl;
	pointerToArray[arrayName]=newArray;
      }
	
     
      else if (strcmp(tmpString1,"construct")==0){
	double x1=0,x2=0,x3=0,x4=0,x5=0,x6=0,x7=0,x8=0,x9=0,x10=0,x11,x12; 
	double posx,posy,posz;
	char name[100];
	char mothersName[100];
	char material[100];
	//	G4CSGSolid* solid=NULL;
	G4VSolid* solid=NULL;
	G4String solidName="sol_";
	char rotMatrix[100]="norot";
	char sensitiveDet[100]="dead";
	int  volumeID=0;
	char actualFieldName[100]="nofield";

	if (strcmp(tmpString2,"tubs")==0){
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  solid = new G4Tubs(solidName,x1*mm,x2*mm,x3*mm,x4*deg,x5*deg);
	}
	else if (strcmp(tmpString2,"cons")==0){
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,&x7,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  solid = new G4Cons(solidName,x1*mm,x2*mm,x3*mm,x4*mm,x5*mm,x6*deg,x7*deg);
	}
	else if (strcmp(tmpString2,"box")==0){
	  //	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %s %lf %lf %lf %s %s",
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  //	  G4cout<<"DEBUG KAMIL: xxx1="<<xxx1<<",  xxx2="<<xxx2<<",  xxx3="<<xxx3<<G4endl;
	  solid = new G4Box(solidName,x1*mm,x2*mm,x3*mm);
	}
        else if ((strcmp(tmpString2,"trd")==0)||(strcmp(tmpString2,"trd90y")==0)) {
          sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
                 name,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName,rotMatrix);
          sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
          solidName+=name;
          solid = new G4Trd(solidName,x1*mm,x2*mm,x3*mm,x4*mm,x5*mm);
        }
	else if (strcmp(tmpString2,"sphere")==0){
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  solid = new G4Sphere(solidName,x1*mm,x2*mm,x3*deg,x4*deg,x5*deg,x6*deg);
	}
	else if ((strcmp(tmpString2,"polyconeA")==0)||(strcmp(tmpString2,"polyconeB")==0)){
	  G4bool polyconeA=true; if (strcmp(tmpString2,"polyconeB")==0) polyconeA=false;
	  char zPlane[100]; double* zPLANE;
	  char rInner[100]; double* rINNER;
	  char rOuter[100]; double* rOUTER;
	  int numZPlanes;
	  if (polyconeA) {
	    sscanf(&line[0],"%*s %*s %*s %s %lf %lf %d %s %s %s %s %lf %lf %lf %s %s",
		   name,&x1,&x2,&numZPlanes,zPlane,rInner,rOuter,material,&posx,&posy,&posz,mothersName,rotMatrix);
	    sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*d %*s %*s %*s %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  }
	  else {  // polyconeB
	    sscanf(&line[0],"%*s %*s %*s %s %lf %lf %d %s %s %s %lf %lf %lf %s %s",
		   name,&x1,&x2,&numZPlanes,zPlane,rInner,material,&posx,&posy,&posz,mothersName,rotMatrix);
	    sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*d %*s %*s %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  }
	  solidName+=name;
	  G4cout<<name<<G4endl;
	  //	  solid = new G4Sphere(solidName,x1*mm,x2*mm,x3*deg,x4*deg,x5*deg,x6*deg);
	  //	  double* zPLANE = pointerToArray[zPlane];
	  iterArray = pointerToArray.find(zPlane);
	  if (iterArray==pointerToArray.end()) {  // array does not exist
	    G4cout<<"\n\n musrDetectorConstruction(): array \""<<zPlane<<"\" requested for the volume \""
		  <<name<<"\",\n  but the array was not found -> was it defined?"<<G4endl;
	    G4cout << "S T O P    F O R C E D"<<G4endl;
	    G4cout << line << G4endl;
	    exit(1);
	  }
	  else {
	    zPLANE = iterArray->second;
	  }
	  G4cout<<"zPLANE="; for (int iiiii=0; iiiii<numZPlanes; iiiii++) {G4cout<<zPLANE[iiiii]<<",";} G4cout<<G4endl;
	  //
	  iterArray = pointerToArray.find(rInner);
	  if (iterArray==pointerToArray.end()) {  // array does not exist
	    G4cout<<"\n\n musrDetectorConstruction(): array \""<<rInner<<"\" requested for the volume \""
		  <<name<<"\",\n  but the array was not found -> was it defined?"<<G4endl;
	    G4cout << "S T O P    F O R C E D"<<G4endl;
	    G4cout << line << G4endl;
	    exit(1);
	  }
	  else {
	    rINNER = iterArray->second;
	  }
	  G4cout<<"rINNER="; for (int iiiii=0; iiiii<numZPlanes; iiiii++) {G4cout<<rINNER[iiiii]<<",";} G4cout<<G4endl;
	  //
	  if (polyconeA) {
	    iterArray = pointerToArray.find(rOuter);
	    if (iterArray==pointerToArray.end()) {  // array does not exist
	      G4cout<<"\n\n musrDetectorConstruction(): array \""<<rOuter<<"\" requested for the volume \""
		    <<name<<"\",\n  but the array was not found -> was it defined?"<<G4endl;
	      G4cout << "S T O P    F O R C E D"<<G4endl;
	      G4cout << line << G4endl;
	      exit(1);
	    }
	    else {
	      rOUTER = iterArray->second;
	    }
	    G4cout<<"rOUTER="; for (int iiiii=0; iiiii<numZPlanes; iiiii++) {G4cout<<rOUTER[iiiii]<<",";} G4cout<<G4endl; 
	  }
	  //
	  if (polyconeA) {
	    solid = new G4Polycone(solidName,x1*deg,x2*deg,numZPlanes,zPLANE,rINNER,rOUTER);
	  }
	  else {  //  polyconeB
	   solid = new G4Polycone(solidName,x1*deg,x2*deg,numZPlanes,zPLANE,rINNER);
	  } 
	}
	else if (strcmp(tmpString2,"para")==0){  // NOT YET TESTED
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  solid = new G4Para(solidName,x1*mm,x2*mm,x3*mm,x4*deg,x5*deg,x6*deg);
	}
	else if (strcmp(tmpString2,"torus")==0){  // added JSL. Torus piece, Rmin (bore), Rmax (outer), Rtorus (swept), pSPhi (start angle), pDPhi (swept angle)
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  solid = new G4Torus(solidName,x1*mm,x2*mm,x3*mm,x4*deg,x5*deg);
	}
        else if (strcmp(tmpString2,"cylpart")==0){  // Volume introduced by Pavel Bakule on 12 May 2009
          sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %s %lf %lf %lf %s %s",
                 name,&x1,&x2,&x3,&x4,material,&posx,&posy,&posz,mothersName,rotMatrix);
          sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
          solidName+=name;
          G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
          G4Box* solidSubtractedBox = new G4Box("solidSubtractedBox",x2*mm,(x2-x4)*mm,x3*mm+roundingErr);
          G4Tubs* solidCylinder = new G4Tubs("solidCylinder",0.*mm,x2*mm,x3*mm,0.*deg,180.*deg);
          solid = new G4SubtractionSolid(solidName, solidCylinder, solidSubtractedBox);
        }
	else if (strcmp(tmpString2,"uprofile")==0){
	  // Create a U-profile geometry.  x1, x2, x3 define the outer dimensions of the U-profile (as a box),
	  //                               x4 is the wall thickness of the U-profile.  The centre of the U-profile
          //                               is in the centre of the box defined by x1,x2,x3.
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  
	  G4double roundingErr=0.01*mm;
	  G4Box* box1 = new G4Box("Box1",x1*mm,x2*mm,x3*mm);
	  G4Box* box2 = new G4Box("Box2",(x1-x4)*mm,(x2-x4/2.+roundingErr)*mm,x3*mm);
	  G4RotationMatrix rot(0,0,0);
	  G4ThreeVector zTrans(0,x4/2.*mm,0);
	  G4Transform3D transform(rot,zTrans);
	  solid =  new G4SubtractionSolid(solidName, box1, box2, transform);
	}
	else if (strcmp(tmpString2,"BarWithBevelledEdgesX")==0){
	  // box, which has "cut out" edges.
	  //       x1,x2,x3 ... dimensions of box (half-lengths)
	  //       x4       ... full width, which will be cut out at the edge (x4 from one side, and the same x4 from the other side).
	  //                    four edges will be cut out (edges parallel with the x direction)
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;

	  G4Box* box1 = new G4Box("Box1",x1*mm,x2*mm,x3*mm);
	  G4Box* box2 = new G4Box("Box2",(x1+1.0)*mm,x4*sqrt(2.)*mm,x4*sqrt(2.)*mm);
	  G4RotationMatrix rot(0,45*deg,0);
	  G4ThreeVector zTransA(0,x2*mm,x3*mm);
	  G4ThreeVector zTransB(0,-x2*mm,x3*mm);
	  G4ThreeVector zTransC(0,x2*mm,-x3*mm);
	  G4ThreeVector zTransD(0,-x2*mm,-x3*mm);
	  G4Transform3D transformA(rot,zTransA);
	  G4Transform3D transformB(rot,zTransB);
	  G4Transform3D transformC(rot,zTransC);
	  G4Transform3D transformD(rot,zTransD);
	  G4SubtractionSolid* box3 =  new G4SubtractionSolid("tmpBox3", box1, box2, transformA);
	  G4SubtractionSolid* box4 =  new G4SubtractionSolid("tmpBox4", box3, box2, transformB);
	  G4SubtractionSolid* box5 =  new G4SubtractionSolid("tmpBox5", box4, box2, transformC);
	  solid =  new G4SubtractionSolid(solidName, box5, box2, transformD);
	}
	else if (strcmp(tmpString2,"alcSupportPlate")==0){
	  // Create an ALC holder geometry:  x1 half-width of the holder (as a box),
          //                                 x2 half-height of the spacer 
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  
	  G4Box* box1 = new G4Box("Box1",x1*mm,4.7*mm,130*mm);
	  G4Box* box2 = new G4Box("Box2",(x1-0.4)*mm,3*mm,130*mm);
	  G4RotationMatrix rot(0,0,0);
	  G4ThreeVector zTrans(0,1.3*mm,0);
	  G4Transform3D transform(rot,zTrans);
	  G4SubtractionSolid* solid_1 =  new G4SubtractionSolid("Drzak", box1, box2, transform);
	  if (x2!=0) {
	    G4Box* box3 = new G4Box("Box3",12.5*mm,4.5*mm,4*mm);
	    G4ThreeVector zTrans2(0,(-4.7-x2)*mm,0);
	    G4Transform3D transform2(rot,zTrans2);
	    solid = new G4UnionSolid("solidName", solid_1, box3, transform2);
	  }
	  else {
	    solid = solid_1;
	  }
	  
	}
	else if (strcmp(tmpString2,"TubeWithTubeHole")==0) {
	  // Create a tube with a partial hole inside it:        ----------
          //                                                     |        |
          //                                                     |        |
          //                                                     |     ___|
          //                                                     |    | 6
          //                                                     |    |
          //                                                     |    |
          //                                                     |    |
          //                                                     |    |___
          //                                                     |        |
          //                                                     |        |
          //                                                     |        |
          //                                                     ----------
	  // First 5 parameters as for the outer tube, the 6th parameter is the depth of the hole.
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Tubs* solidInnerDetTube = new G4Tubs("SolidInnerDetTube",0,x1*mm,x6/2*mm+roundingErr,x4*deg,x5*deg);
	  G4Tubs* solidOuterDetTube = new G4Tubs("SolidOuterDetTube",0,x2*mm,x3*mm,x4*deg,x5*deg);
	  G4RotationMatrix rot(0,0,0);
	  G4ThreeVector zTrans(0,0,(x6/2.-x3)*mm);
	  G4Transform3D transform(rot,zTrans);
	  solid =  new G4SubtractionSolid(solidName, solidOuterDetTube, solidInnerDetTube, transform);
	}
	else if (strcmp(tmpString2,"TubeWithHoleAndTubeHole")==0) {
	  // Create a tube with a partial hole inside it:        ----------
          //                                                     |        |
          //                                                     |        |
          //                                                     |     _7_|
          //                                                     |    |6 
          //                                                     ------
          //                                                            
          //                                                     ------
          //                                                     |    |___
          //                                                     |        |
          //                                                     |        |
          //                                                     |        |
          //                                                     ----------
	  // First 5 parameters as for the outer tube, the 6th parameter is the depth of the hole.
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,&x7,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Tubs* solidInnerDetTube = new G4Tubs("SolidInnerDetTube",0,x6*mm,x7/2*mm+roundingErr,x4*deg,x5*deg);
	  G4Tubs* solidOuterDetTube = new G4Tubs("SolidOuterDetTube",x1*mm,x2*mm,x3*mm,x4*deg,x5*deg);
	  G4RotationMatrix rot(0,0,0);
	  G4ThreeVector zTrans(0,0,(x7/2.-x3)*mm);
	  G4Transform3D transform(rot,zTrans);
	  solid =  new G4SubtractionSolid(solidName, solidOuterDetTube, solidInnerDetTube, transform);
	}
	else if (strcmp(tmpString2,"TubeWithHolePlusTubeHole")==0) {
	  // Create a tube with a partial hole inside it:        ----------
          //                                                     |        |
          //                                                     |     _8_| 7
          //                                                     |    | 
          //                                                     |    |___  
          //                                                     |        | 6
          //                                                     |        |
          //                                                     ----------
          //                                                            
          //                                                     ----------
          //                                                     |        |
          //                                                     |     ___|
          //                                                     |    |
          //                                                     |    |___
          //                                                     |        |
          //                                                     ----------
	  // First 5 parameters as for the outer tube, the 6th, 7th and 8th define the second hole.
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %lf %lf %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,&x7,&x8,material);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*g %*g %*s %lf %lf %lf %s %s %s %d %s",
		 &posx,&posy,&posz,mothersName,rotMatrix,sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Tubs* solidInnerDetTube = new G4Tubs("SolidInnerDetTube",x6*mm-roundingErr,x7*mm+roundingErr,x8/2*mm+roundingErr,x4*deg,x5*deg);
	  G4Tubs* solidOuterDetTube = new G4Tubs("SolidOuterDetTube",x1*mm,x2*mm,x3*mm,x4*deg,x5*deg);
	  G4RotationMatrix rot(0,0,0);
	  G4ThreeVector zTrans(0,0,(x8/2.-x3)*mm);
	  G4Transform3D transform(rot,zTrans);
	  solid =  new G4SubtractionSolid(solidName, solidOuterDetTube, solidInnerDetTube, transform);
	}
	else if (strcmp(tmpString2,"tubsbox")==0){
	  // Create a tube, from which center a box is cut out.  x1=box half-width; x2,x3,x4,x5 define the tube.
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Box* solidInnerDetBox = new G4Box("SolidInnerDetBox",x1*mm,x1*mm,x3*mm+roundingErr);
	  G4Tubs* solidOuterDetTube = new G4Tubs("SolidOuterDetTube",0.*mm,x2*mm,x3*mm,x4*deg,x5*deg);
	  solid =  new G4SubtractionSolid(solidName, solidOuterDetTube, solidInnerDetBox);
	}
	else if (strcmp(tmpString2,"tubsbox2")==0){
	  // Create a tube, from which center a box is cut out.  More general box and tube than in "tubsbox".
	  // x1,x2,x3=box half-widths; x4,x5,x6,x7,x8 define the tube.
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %lf %lf %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,&x7,&x8,material);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*g %*g %*s %lf %lf %lf %s %s %s %d %s",
		 &posx,&posy,&posz,mothersName,rotMatrix,sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Box* solidInnerDetBox2 = new G4Box("SolidInnerDetBox2",x1*mm,x2*mm,x3*mm+roundingErr);
	  G4Tubs* solidOuterDetTube2 = new G4Tubs("SolidOuterDetTube2",x4*mm,x5*mm,x6*mm,x7*deg,x8*deg);
	  solid =  new G4SubtractionSolid(solidName, solidOuterDetTube2, solidInnerDetBox2);
	}
	else if (strcmp(tmpString2,"boxbox")==0){
	  // Create a box, from which center a box is cut out.
	  // x1,x2,x3=box half-widths of the inner box (opening); x4,x5,x6 define the big box.
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,material);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*s %lf %lf %lf %s %s %s %d %s",
		 &posx,&posy,&posz,mothersName,rotMatrix,sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Box* solidInnerDetBox = new G4Box("SolidInnerDetBox",x1*mm+roundingErr,x2*mm+roundingErr,x3*mm+roundingErr);
	  G4Box* solidOuterDetBox = new G4Box("SolidOuterDetBox",x4*mm,x5*mm,x6*mm);
	  solid =  new G4SubtractionSolid(solidName, solidOuterDetBox, solidInnerDetBox);
	}
	else if (strcmp(tmpString2,"GPSforward")==0){
	  // Create a box, from which a cone is cut out:
	  // x1, x2, x3 = box half-widths; 
	  // x4, x5     = radii of the cone (at the two faces of the box) that will be cut out
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Box* GPS_SolidDetBox = new G4Box("GPS_SolidDetBox",x1*mm,x2*mm,x3*mm);
	  G4Cons* GPS_SolidDetCons = new G4Cons("GPS_SolidDetCons",0.,x4*mm,0.,x5*mm,x3*mm+roundingErr,0.,360.);
	  solid =  new G4SubtractionSolid(solidName, GPS_SolidDetBox, GPS_SolidDetCons);
	}
	else if (strcmp(tmpString2,"GPSbackward")==0){
	  // Create a box, from which a trapezoid (with dx=dy) is cut out:
	  // x1, x2, x3 = box half-widths; 
	  // x4, x5     = dx1=dy1 and dx2=dy2 of the trapezoid
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Box* GPS_SolidDetBox2 = new G4Box("GPS_SolidDetBox2",x1*mm,x2*mm,x3*mm);
	  G4Trd* GPS_SolidDetTrd2 = new G4Trd("GPS_SolidDetTrd2",x4*mm,x5*mm,x4*mm,x5*mm,x3*mm+roundingErr);
	  solid =  new G4SubtractionSolid(solidName, GPS_SolidDetBox2, GPS_SolidDetTrd2);
	}
	else if (strcmp(tmpString2,"GPSbackwardVeto")==0){
	  // Create a trapezoid, from which a trapezoid is cut out:
	  // x1, x2, x3, x4, x5 = half-dimensions of the outer trapezoid;
	  // x6, x7, x8, x9     = half-dimensions of the inner trapezoid  (it is expected that dz=x5 is the same for both trapezoids)
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %lf %lf %lf %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,&x7,&x8,&x9,material);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*g %*g %*g %*s %lf %lf %lf %s %s %s %d %s",
		 &posx,&posy,&posz,mothersName,rotMatrix,sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Trd* GPS_OuterTrd = new G4Trd("GPS_OuterTrd",x1*mm,x2*mm,x3*mm,x4*mm,x5*mm);
	  G4Trd* GPS_InnerTrd = new G4Trd("GPS_InnerTrd",x6*mm,x7*mm,x8*mm,x9*mm,x5*mm+roundingErr);
	  solid =  new G4SubtractionSolid(solidName,GPS_OuterTrd,GPS_InnerTrd);
	}
	else if (strcmp(tmpString2,"tubeWithWindows")==0){
	  // x1 ... inner radius of the tube
	  // x2 ... outer radius of the tube
	  // x3 ... half-length of the tube
	  // x4 ... radius of the backward window
	  // x5 ... distance between the center of the backward window and the end of the shield
	  // x6 ... radius of the forward window
	  // x7 ... distance between the center of the forward window and the end of the shield
	  //
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %lf %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,&x7,material);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*g %*s %lf %lf %lf %s %s %s %d %s",
		 &posx,&posy,&posz,mothersName,rotMatrix,sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Tubs* solidShield = new G4Tubs("SolidShield",x1*mm,x2*mm,x3*mm,0.,360.);
	  G4Tubs* solidWindF = new G4Tubs("SolidWindF",0.,x4*mm,x2*mm,0.,360.);
	  G4Tubs* solidWindB = new G4Tubs("SolidWindB",0.,x6*mm,x2*mm,0.,360.);
	  G4RotationMatrix* rot = new G4RotationMatrix(0,90*deg,0);
	  G4ThreeVector zTransF(0.,x2*mm+roundingErr,(x5-x3)*mm);
	  G4ThreeVector zTransB(0.,-x2*mm+roundingErr,(x7-x3)*mm);
	  G4SubtractionSolid* solidF1 =  new G4SubtractionSolid("solidF1", solidShield, solidWindF, rot, zTransF);
	  solid =  new G4SubtractionSolid(solidName, solidF1, solidWindB, rot, zTransB);
	}
	else if (strcmp(tmpString2,"GPDcollimator")==0){
	  // Create a box, from which a box is cut out.  x1, x2, x3 = box half-widths; 
	  //           x4,x5,x6,x7 define the tube, x8, x9 and x10 are the distances between the tube and box centres.
	  //           x11, x12 are the half-withs of the ractangular opening in the collimator
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %s",
		 name,&x1,&x2,&x3,&x4,&x5,&x6,&x7,&x8,&x9,&x10,&x11,&x12,material);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*g %*g %*g %*g %*g %*g %*g %*s %lf %lf %lf %s %s %s %d %s",
		 &posx,&posy,&posz,mothersName,rotMatrix,sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4Box* solidDetBox = new G4Box("SolidDetBox",x1*mm,x2*mm,x3*mm);
	  G4Box* solidHole   = new G4Box("SolidDetBox",x11*mm,x2*mm+0.1,x12*mm);
	  G4Tubs* solidDetTube = new G4Tubs("SolidDetTube",0.,x4*mm,x5*mm,x6*deg,x7*deg);
	  G4RotationMatrix* yRot = new G4RotationMatrix();
	  G4ThreeVector zTrans(-x8*mm,-x9*mm,-x10*mm);
	  G4SubtractionSolid* solidPart1 =  new G4SubtractionSolid("solidPart1", solidDetBox, solidDetTube, yRot, zTrans);
	  solid =  new G4SubtractionSolid(solidName,solidPart1,solidHole);
	}
	else if (strcmp(tmpString2,"tubsboxsegm")==0){
	  // Create a volume that looks like an intersection of tube and box.
	  char orientation[100];
	  sscanf(&line[0],"%*s %*s %*s %s %s %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,orientation,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Box* solidDetBox = new G4Box("SolidDetBox",x2*mm,x2*mm,x3*mm+roundingErr);
	  G4Tubs* solidDetTube = new G4Tubs("SolidDetTube",0.*mm,x2*mm,x3*mm,x4*deg,x5*deg);
	  G4RotationMatrix* yRot = new G4RotationMatrix;
	  G4ThreeVector zTrans;
	  if (strcmp(orientation,"D")==0) zTrans=G4ThreeVector((x1-x2)*mm,(-x1-x2)*mm,0);
	  else if (strcmp(orientation,"U")==0) zTrans=G4ThreeVector((x2-x1)*mm,(x1+x2)*mm,0);
	  else if (strcmp(orientation,"R")==0) zTrans=G4ThreeVector((-x1-x2)*mm,(x2-x1)*mm,0);
	  else if (strcmp(orientation,"L")==0) zTrans=G4ThreeVector((x1+x2)*mm,(x1-x2)*mm,0);
	  else {
	    G4cout<<"Unknown orientation of the tubsboxsegm volume!!"
		  <<"  orientation="<<orientation<<G4endl;
	    ReportGeometryProblem(line);
	  }
	  solid =  new G4IntersectionSolid(solidName, solidDetTube, solidDetBox, yRot, zTrans);
	}
	else if (strcmp(tmpString2,"GPDsampleHolderA")==0){
	  // First part of the GPD sample holder, where posx, posy, posz = centre of the whole (long) tube 
	  //                                                      (=111.25mm below the centre of the holes)
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d",sensitiveDet,&volumeID);
	  solidName+=name;
	  G4double upperPartHalfHeight = 65*mm;
	  G4double lowerPartHalfHeight = (287.5-65)/2*mm;
	  G4double halfHeight = upperPartHalfHeight+lowerPartHalfHeight;
	  G4double innerR = 37.*mm; G4double outerR = 37.5*mm;
	  
	  //	  G4Box* solidDetBox = new G4Box("SolidDetBox",x2*mm,x2*mm,x3*mm+roundingErr);
	  G4Tubs* solidGPDTubeA1 = new G4Tubs("SolidGPDTubeA1",innerR,outerR,halfHeight,0,360);
	  G4Box*  solidGPDBoxA2  = new G4Box ("SolidGPDBoxA2",10*mm,38*mm, 70*mm);
	  G4Box*  solidGPDBoxA5  = new G4Box ("solidGPDBoxA5",5*mm,40*mm,30*mm); 

	  G4RotationMatrix* yRotA12 = new G4RotationMatrix();
	  G4ThreeVector zTransA12( 30*mm,0, (111.25+20)*mm);
	  G4ThreeVector zTransA13(-30*mm,0, (111.25+20)*mm);
	  G4SubtractionSolid* solidA12 =  new G4SubtractionSolid("solidA12", solidGPDTubeA1, solidGPDBoxA2, yRotA12, zTransA12);
	  G4SubtractionSolid* solidA123 =  new G4SubtractionSolid("solidA123", solidA12 , solidGPDBoxA2, yRotA12, zTransA13);
	  G4ThreeVector zTransA5(0,0,111.25*mm);
	  solid =  new G4SubtractionSolid(solidName, solidA123, solidGPDBoxA5, yRotA12, zTransA5);
	}
	else if (strcmp(tmpString2,"GPDmHolder")==0){
	  // Light guide that holds m0 in its position
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d",sensitiveDet,&volumeID);
	  solidName+=name;
	  G4Box* solidGPDcutOut = new G4Box ("solidGPDcutOut",x1*mm,x1*mm,(x3+0.01)*mm);
	  G4Box* solidGPDmHolder = new G4Box ("solidGPDmHolder",sqrt((double)2)*x1*mm,x2*mm,x3*mm);
	  //	  G4RotationMatrix* rot = new G4RotationMatrix(45*deg,0,0);
	  G4RotationMatrix* rot = new G4RotationMatrix(G4ThreeVector(0,0,1),45*deg);
	  //	  G4RotationMatrix* rot = new G4RotationMatrix();
	  G4ThreeVector  trans(0,x2*mm,0);
	  solid =  new G4SubtractionSolid(solidName,solidGPDmHolder,solidGPDcutOut,rot,trans);
	  //	  solid =  new G4SubtractionSolid(solidName,solidGPDcutOut,solidGPDmHolder,rot,trans);
	}
	else if (strcmp(tmpString2,"cruciform")==0){
	  // JSL: Create a solid cruciform (union of 3 mutually perpendicular cylinders). Top port can be different to bottom.
	  // x1=radius of main (+-z) x2=radius of +-x and -y, x3=radius of +y x4=z extent x5=x,y extent
	  // could enclose another of these inside, filled with vacuum
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf %lf %lf %s %lf %lf %lf %s %s",
		 name,&x1,&x2,&x3,&x4,&x5,material,&posx,&posy,&posz,mothersName,rotMatrix);
	  sscanf(&line[0],"%*s %*s %*s %*s %*g %*g %*g %*g %*g %*s %*g %*g %*g %*s %*s %s %d %s",sensitiveDet,&volumeID,actualFieldName);
	  solidName+=name;
	  //G4double roundingErr=0.01*mm;  // to avoid some displaying problems of the subtracted volumes
	  G4Tubs* solidMainBore       = new G4Tubs("solidMainBore"      ,0.*mm,x1*mm,x4*mm,0*deg,360*deg);
	  G4Tubs* solidHorizCrossBore = new G4Tubs("solidHorizCrossBore",0.*mm,x2*mm,x5*mm,0*deg,360*deg);
	  G4Tubs* solidBottomBore     = new G4Tubs("solidBottomBore"    ,0.*mm,x2*mm,x5/2*mm,0*deg,360*deg);
	  G4Tubs* solidTopBore        = new G4Tubs("solidTopBore"       ,0.*mm,x3*mm,x5/2*mm,0*deg,360*deg);
	  G4RotationMatrix* rotx = new G4RotationMatrix(G4ThreeVector(0.,1.,0.),90.*deg);
	  G4RotationMatrix* roty = new G4RotationMatrix(G4ThreeVector(1.,0.,0.),90.*deg);
	  G4ThreeVector nowhere( 0,0,0);
	  G4ThreeVector UpOffset( 0., x5/2.*mm, 0.);
	  G4ThreeVector DownOffset( 0., -x5/2.*mm, 0.);
	  G4UnionSolid* partXZonly = new G4UnionSolid("partXZonly", solidMainBore, solidHorizCrossBore, rotx, nowhere);
	  G4UnionSolid* partXZBonly = new G4UnionSolid("partXZBonly", partXZonly, solidBottomBore, roty, DownOffset);
	  solid =  new G4UnionSolid(solidName, partXZBonly, solidTopBore, roty, UpOffset);
	}
	else ReportGeometryProblem(line);

	G4ThreeVector position = G4ThreeVector (posx*mm,posy*mm,posz*mm);
	//	G4cout << "New volume: "<<tmpString2<<" "<<name<<", solid geometry parameters="<<x1<<" "<<x2<<" "<<x3<<" "<<x4<<" "<<x5
	//	       << ", position="<<position<<", mother="<<mothersName<<G4endl;


	G4LogicalVolume* mothersVolume;
	if (strcmp(name,"World")==0) { mothersVolume=NULL; }
	else {
	  mothersVolume	= FindLogicalVolume(mothersName);
	  if (mothersVolume==NULL) {
	    G4cout << "ERROR! musrDetectorConstruction::Construct():"<<G4endl;
	    G4cout << "       Logical Volume \"" << mothersName <<"\" not found!"<<G4endl;
	    G4cout << "       (requested for the definition of the volume \""<<name<<"\")"<<G4endl;
	    G4cout << "S T O P    F O R C E D"<<G4endl;
	    exit(1);
	  }
	}
	
	G4cout<<"volumeID="<<volumeID<<"\t ";	
	G4RotationMatrix* pRot = pointerToRotationMatrix[rotMatrix];
	//	G4cout << "rotMatrix="<<rotMatrix<<"  pRot="<<pRot<<"        ";
	if (pRot!=NULL) {G4cout<<"    rotated, ";}                // OK, rotation matrix found.
	else if ((strcmp(rotMatrix,"norot"))) {                       // Problem, matrix not found.
	  G4cout <<"Rotation Matrix \""<<rotMatrix<<"\" not found (not defined at this point)!"
		 <<"    Check the geometry!"<<G4endl;
	  G4cout <<"S T O P    F O R C E D"<<G4endl;
	  ReportGeometryProblem(line);
	}
	else {G4cout<<"non-rotated, ";}
	if (strcmp(sensitiveDet,"dead")) {G4cout<<"     sensitive:   ";}
	else {G4cout<<" non-sensitive:   ";}
		 
        // For trapezoid "trd90y" rotate the trapezoid by 90 degrees in y direction
	// (in addition to the requested rotation)
	if (strcmp(tmpString2,"trd90y")==0) {
	  pRot->rotateY(90.0*deg);
        }

	G4FieldManager* pFieldMan = pointerToField[actualFieldName];
        if (pFieldMan!=NULL) {G4cout<<"    volume with field, ";}
        else if ((strcmp(actualFieldName,"nofield"))) {
          G4cout <<"Field Manager \""<<actualFieldName<<"\" not found (not defined at this point)!"
                 <<"    Check the geometry!"<<G4endl;
          G4cout <<"S T O P    F O R C E D"<<G4endl;
          ReportGeometryProblem(line);
        }

	G4Material* MATERIAL=CharToMaterial(material);
	G4String logicName="log_";  logicName+=name;
	G4LogicalVolume* logicVolume = new G4LogicalVolume(solid,MATERIAL,logicName,pFieldMan,0,0);
	//	G4cout << "musrDetectorConstruction.cc: logicVolume created ="<<logicVolume<<G4endl;
	G4String physName="phys_";  physName+=name;
	G4VPhysicalVolume* physiVolume = new G4PVPlacement(pRot,              // rotation 
					position,
					logicVolume,    // its logical volume
					physName,       // its name
					mothersVolume,  // its mother  volume
					false,           // no boolean operations
					0,               // no field specific to volume
					checkOverlap);  // Check for overlap
	//	G4cout << "musrDetectorConstruction.cc physiVolume created ="<<physiVolume<<G4endl;
	if (strcmp(name,"World")==0)  { pointerToWorldVolume=physiVolume; G4cout<<"World Volume"<<G4endl;}
	
	// If the name of the volume contains the string "save", it will be treated specifically 
        // (a position of where a particle went through the volume will be saved)
	if (strstr(name,"save")!=NULL) {
	  if (volumeID!=0) {    // do not store hits in special "save" volume if ID of this volume is 0 
	                        // (due to difficulties to distinguish between ID=0 and no save volume when using std::map)
	    mySteppingAction->SetLogicalVolumeAsSpecialSaveVolume(logicName,volumeID);
	    musrRootOutput::GetRootInstance()->SetSpecialSaveVolumeDefined();
	  }
	}

	// Unless specified as "dead", set the volume sensitive volume:
	if (strcmp(sensitiveDet,"dead")) {
	  if (strcmp(sensitiveDet,"musr/ScintSD")==0) {
	    if(!aScintSD) {
	      G4SDManager* SDman = G4SDManager::GetSDMpointer();
	      G4String scintSDname = sensitiveDet;
	      aScintSD = new musrScintSD( scintSDname );
	      SDman->AddNewDetector( aScintSD );
	      G4cout<<"musrDetectorConstruction.cc:  aScintSD added: "<<aScintSD->GetFullPathName()<<G4endl;
	    }
	    logicVolume->SetSensitiveDetector( aScintSD );
	  }
	  else {
	    G4cout<<" musrDetectorConstruction.cc: unknown sensitive detector \""<<sensitiveDet<<"\" requested!"<<G4endl;
	    G4cout<<"\""<<line<<"\""<<G4endl;
	    G4cout<<"        S T O P    F O R C E D !!!"<<G4endl;
	    exit(1);
	  }
	}

	//  Set the volume ID (used only for the Root output).
	if (volumeID!=0) {
	  myRootOutput->SetVolumeIDMapping(logicName,volumeID);
	}
	
	// If the volume name is "Target", "M0", "M1" or "M2", let's save muon polarisation and time in these volumes:
        if ((strcmp(name,"Target")==0)||(strcmp(name,"target")==0)) {
	  musrRootOutput::store_muTargetTime = true; musrRootOutput::store_muTargetPolX = true;
	  musrRootOutput::store_muTargetPolY = true; musrRootOutput::store_muTargetPolZ = true;
	  musrRootOutput::store_muTargetMomX = true;
	  musrRootOutput::store_muTargetMomY = true; musrRootOutput::store_muTargetMomZ = true;
	}
	if ((strcmp(name,"M0")==0)||(strcmp(name,"m0")==0))  {
	  musrRootOutput::store_muM0Time = true; musrRootOutput::store_muM0PolX = true;
	  musrRootOutput::store_muM0PolY = true; musrRootOutput::store_muM0PolZ = true;
	}
	if ((strcmp(name,"M1")==0)||(strcmp(name,"m1")==0))  {
	  musrRootOutput::store_muM1Time = true; musrRootOutput::store_muM1PolX = true;
	  musrRootOutput::store_muM1PolY = true; musrRootOutput::store_muM1PolZ = true;
	}
	if ((strcmp(name,"M2")==0)||(strcmp(name,"m2")==0))  {
	  musrRootOutput::store_muM2Time = true; musrRootOutput::store_muM2PolX = true;
	  musrRootOutput::store_muM2PolY = true; musrRootOutput::store_muM2PolZ = true;
	}
      }

      else if (strcmp(tmpString1,"visattributes")==0){
	sscanf(&line[0],"%*s %*s %*s %s",tmpString3);
	if (strncmp(tmpString2,"log_",4)==0) {
	  G4LogicalVolume* pLogVol = FindLogicalVolume(tmpString2);
	  if (pLogVol==NULL) {
	    sprintf(eMessage,"musrDetectorConstruction.cc::Construct(): visattributes requested for %s, but this volume was not found.",tmpString2); 
	    musrErrorMessage::GetInstance()->musrError(WARNING,eMessage,false);
	  }	
	  else {SetColourOfLogicalVolume(pLogVol,tmpString3);}
	}
	else {
	  G4LogicalVolumeStore* pLogStore = G4LogicalVolumeStore::GetInstance();
	  if (pLogStore==NULL) {
	    G4cout<<"ERROR:  musrDetectorConstruction.cc:    G4LogicalVolumeStore::GetInstance()  not found!"<<G4endl;
	  }
	  else {
	    for (unsigned int i=0; i<pLogStore->size(); i++) {
	      G4LogicalVolume* pLogVol=pLogStore->at(i);
	      G4String materialName=pLogVol->GetMaterial()->GetName(); 
	      if (tmpString2==materialName) {
		SetColourOfLogicalVolume(pLogVol,tmpString3);
	      }
	    }
	  }
	}
      }

      // cks:  Optical Boundary  (needed only when simulating optical photons)
      else if (strcmp(tmpString1,"opticalSurface")==0) {
	if (musrParameters::boolG4OpticalPhotons) {
	  char optSurfaceName[100];
	  char physVolName1[100];
	  char physVolName2[100];
	  char type[100];
	  char finish[100];
	  char model[100];
	  char materialPropertiesTableName[100]="Undefined";
	  sscanf(&line[0],"%*s %*s %s %s %s %s %s %s %s",optSurfaceName,physVolName1,physVolName2,type,finish,model,materialPropertiesTableName);
	  G4VPhysicalVolume* pPhysVol1 = FindPhysicalVolume(physVolName1);
	  G4VPhysicalVolume* pPhysVol2 = FindPhysicalVolume(physVolName2);
	  if ((pPhysVol1==NULL)||(pPhysVol2==NULL)) {
	    G4cout << "ERROR! musrDetectorConstruction::Construct():  Physical Volume not found!"<<G4endl;
	    G4cout << "      ==>  S T O P    F O R C E D"<<G4endl;
	    ReportGeometryProblem(line);
	    exit(1);
	  }
	  
	  G4OpticalSurface* optSurfTMP = new G4OpticalSurface(optSurfaceName);
	  new G4LogicalBorderSurface(optSurfaceName,pPhysVol1,pPhysVol2,optSurfTMP);
	  
	  std::map<std::string,G4SurfaceType>          OpticalTypeMap;
	  std::map<std::string,G4OpticalSurfaceModel>  OpticalModelMap;
	  std::map<std::string,G4OpticalSurfaceFinish> OpticalFinishMap;
	  
	  OpticalTypeMap["dielectric_metal"]=dielectric_metal;             // dielectric-metal interface
	  OpticalTypeMap["dielectric_dielectric"]=dielectric_dielectric;   // dielectric-dielectric interface
	  OpticalTypeMap["dielectric_LUT"]=dielectric_LUT;                 // dielectric-Look-Up-Table interface
	  OpticalTypeMap["firsov"]=firsov;                                 // for Firsov Process
	  OpticalTypeMap["x_ray"]=x_ray;                                   // for x-ray mirror process
	  
	  OpticalModelMap["glisur"]=glisur;                                // original GEANT3 model
	  OpticalModelMap["unified"]=unified;                              // UNIFIED model
	  OpticalModelMap["LUT"]=LUT;                                      // Look-Up-Table model
	  
	  OpticalFinishMap["polished"]=polished;                           // smooth perfectly polished surface
	  OpticalFinishMap["polishedfrontpainted"]=polishedfrontpainted;   // smooth top-layer (front) paint
	  OpticalFinishMap["polishedbackpainted"]=polishedbackpainted;     // same is 'polished' but with a back-paint
	  OpticalFinishMap["ground"]=ground;                               // rough surface
	  OpticalFinishMap["groundfrontpainted"]=groundfrontpainted;       // rough top-layer (front) paint
	  OpticalFinishMap["groundbackpainted"]=groundbackpainted;         // same as 'ground' but with a back-paint  
	  OpticalFinishMap["polishedlumirrorair"]=polishedlumirrorair;     // mechanically polished surface, with lumirror
	  OpticalFinishMap["polishedlumirrorglue"]=polishedlumirrorglue;   // mechanically polished surface, with lumirror & meltmount
	  OpticalFinishMap["polishedair"]=polishedair;                     // mechanically polished surface
	  OpticalFinishMap["polishedteflonair"]=polishedteflonair;         // mechanically polished surface, with teflon
	  OpticalFinishMap["polishedtioair"]=polishedtioair;               // mechanically polished surface, with tio paint
	  OpticalFinishMap["polishedtyvekair"]=polishedtyvekair;           // mechanically polished surface, with tyvek
	  OpticalFinishMap["polishedvm2000air"]=polishedvm2000air;         // mechanically polished surface, with esr film
	  OpticalFinishMap["polishedvm2000glue"]=polishedvm2000glue;       // mechanically polished surface, with esr film & meltmount
	  OpticalFinishMap["etchedlumirrorair"]=etchedlumirrorair;         // chemically etched surface, with lumirror
	  OpticalFinishMap["etchedlumirrorglue"]=etchedlumirrorglue;       // chemically etched surface, with lumirror & meltmount
	  OpticalFinishMap["etchedair"]=etchedair;                         // chemically etched surface
	  OpticalFinishMap["etchedteflonair"]=etchedteflonair;             // chemically etched surface, with teflon
	  OpticalFinishMap["etchedtioair"]=etchedtioair;                   // chemically etched surface, with tio paint
	  OpticalFinishMap["etchedtyvekair"]=etchedtyvekair;               // chemically etched surface, with tyvek
	  OpticalFinishMap["etchedvm2000air"]=etchedvm2000air;             // chemically etched surface, with esr film
	  OpticalFinishMap["etchedvm2000glue"]=etchedvm2000glue;           // chemically etched surface, with esr film & meltmount  
	  OpticalFinishMap["groundlumirrorair"]=groundlumirrorair;         // rough-cut surface, with lumirror
	  OpticalFinishMap["groundlumirrorglue"]=groundlumirrorglue;       // rough-cut surface, with lumirror & meltmount
	  OpticalFinishMap["groundair"]=groundair;                         // rough-cut surface
	  OpticalFinishMap["groundteflonair"]=groundteflonair;             // rough-cut surface, with teflon
	  OpticalFinishMap["groundtioair"]=groundtioair;                   // rough-cut surface, with tio paint
	  OpticalFinishMap["groundtyvekair"]=groundtyvekair;               // rough-cut surface, with tyvek
	  OpticalFinishMap["groundvm2000air"]=groundvm2000air;             // rough-cut surface, with esr film
	  OpticalFinishMap["groundvm2000glue"]=groundvm2000glue;           // rough-cut surface, with esr film & meltmount
	  
	  
	  G4SurfaceType OpticalType            = OpticalTypeMap[type];
	  G4OpticalSurfaceModel OpticalModel   = OpticalModelMap[model];
	  G4OpticalSurfaceFinish OpticalFinish = OpticalFinishMap[finish];
	  if ((OpticalType==0)&&(strcmp(type,"dielectric_metal")!=0)) {
	    G4cout<<"ERROR!  musrDetectorConstruction::Construct(): Optical type \""<<type<<"\" not found!"<<G4endl;
	    G4cout<<"      (Maybe it exists in Geant4 but was not added to musrSim ==> update musrDetectorConstruction.cc file!)"<< G4endl;
	    G4cout << "      ==>  S T O P    F O R C E D"<<G4endl;
	    G4cout<<"   "<<line<<G4endl;
	    exit(1);
	  }
	  if ((OpticalModel==0)&&(strcmp(model,"glisur")!=0)) {
	    G4cout<<"ERROR!  musrDetectorConstruction::Construct(): Optical surface model \""<<model<<"\" not found!"<<G4endl;
	    G4cout<<"      (Maybe it exists in Geant4 but was not added to musrSim ==> update musrDetectorConstruction.cc file!)"<< G4endl;
	    G4cout << "      ==>  S T O P    F O R C E D"<<G4endl;
	    G4cout<<"   "<<line<<G4endl;
	    exit(1);
	  }
	  if ((OpticalFinish==0)&&(strcmp(finish,"polished")!=0)) {
	    G4cout<<"ERROR!  musrDetectorConstruction::Construct(): Optical surface finish \""<<finish<<"\" not found!"<<G4endl;
	    G4cout<<"      (Maybe it exists in Geant4 but was not added to musrSim ==> update musrDetectorConstruction.cc file!)"<< G4endl;
	    G4cout << "      ==>  S T O P    F O R C E D"<<G4endl;
	    G4cout<<"   "<<line<<G4endl;
	    exit(1);
	  }


	  optSurfTMP->SetType(OpticalType);
	  optSurfTMP->SetFinish(OpticalFinish);
	  optSurfTMP->SetModel(OpticalModel);
	  // Assign the "Material properties table" if required by the user:
	  //	  G4cout<<"materialPropertiesTableName="<<materialPropertiesTableName<<G4endl;
	  if (strcmp(materialPropertiesTableName,"Undefined")!=0) {
	    G4MaterialPropertiesTable* MPT_tmp=NULL;
	    itMPT = materialPropertiesTableMap.find(materialPropertiesTableName);
	    if (itMPT==materialPropertiesTableMap.end()) {  // G4MaterialPropertiesTable of this name does not exist --> problem  
	      G4cout<<"\n\n musrDetectorConstruction(): Material Properties Table \""<<materialPropertiesTableName
		    <<"\" should be assigned to G4OpticalSurface \""<<optSurfaceName<<"\""<<G4endl;
	      G4cout<<" but the table was not defined yet (by command /musr/command materialPropertiesTable )"<<G4endl;
	      G4cout << "S T O P    F O R C E D"<<G4endl;
	      G4cout << line << G4endl;
	      exit(1);
	    }
	    else {
	      MPT_tmp = itMPT->second;
	    }
	    optSurfTMP->SetMaterialPropertiesTable(MPT_tmp);
	    //	    optSurfTMP->GetMaterialPropertiesTable()->DumpTable();
	  }
	  G4cout<<"Optical surface \""<<optSurfaceName<<"\" created.  OpticalType="<<OpticalType
		<<"  OpticalFinish="<<OpticalFinish<<"  OpticalModel="<<OpticalModel<<G4endl;
	}
      }

      else if (strcmp(tmpString1,"OPSA")==0){   // optical photon signal analysis
	if (musrParameters::boolG4OpticalPhotons) {
	  musrScintSD* myMusrScintSD = musrScintSD::GetInstance();
	  if (myMusrScintSD==NULL) {
	    sprintf(eMessage,"musrDetectorConstruction.cc::Construct():  musrScintSD::GetInstance() is NULL - no musr/ScintSD set?");
	    musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
	  }
	  char varName[100];
	  double fVarValue;
	  int   iVarValue;
	  sscanf(&line[0],"%*s %*s %s",varName);
	  if (strcmp(varName,"minNrOfDetectedPhotons")==0) {
	    sscanf(&line[0],"%*s %*s %*s %d",&iVarValue);
	    myMusrScintSD -> Set_OPSA_minNrOfDetectedPhotons(iVarValue);
	  }
	  else if (strcmp(varName,"signalSeparationTime")==0) {
	    sscanf(&line[0],"%*s %*s %*s %lf",&fVarValue);
	    myMusrScintSD -> Set_OPSA_SignalSeparationTime(fVarValue*nanosecond);
	  }
	  else if (strcmp(varName,"photonFractions")==0) {
	    double a, b, c, d;
	    sscanf(&line[0],"%*s %*s %*s %lf %lf %lf %lf",&a, &b, &c, &d);
	    myMusrScintSD -> Set_OPSA_variables(a,b,c,d);
	  }
	  else if (strcmp(varName,"eventsForOPSAhistos")==0) {
	    int i_eventID, i_detectorID;
	    sscanf(&line[0],"%*s %*s %*s %d %d",&i_eventID,&i_detectorID);
	    myMusrScintSD -> AddEventIDToMultimapOfEventIDsForOPSAhistos(i_eventID,i_detectorID);
	  }
	  else if (strcmp(varName,"OPSAhist")==0) {
	    int nBins;
	    double min, max;
	    sscanf(&line[0],"%*s %*s %*s %d %lf %lf",&nBins,&min,&max);
	    myMusrScintSD -> SetOPSAhistoBinning(nBins,min*nanosecond,max*nanosecond);
	  }
	  else if (strcmp(varName,"pulseShapeArray")==0) {
	    char fileName[500];
	    sscanf(&line[0],"%*s %*s %*s %s",fileName);
	    myMusrScintSD -> ReadInPulseShapeArray(fileName);
	  }
	  else if (strcmp(varName,"CFD")==0) {
	    double a1, delay, timeShiftOffset;
	    sscanf(&line[0],"%*s %*s %*s %lf %lf %lf",&a1,&delay,&timeShiftOffset);
	    myMusrScintSD -> Set_OPSA_CFD(a1,delay,timeShiftOffset);
	  }
	  else if (strcmp(varName,"APDcells")==0) {
	    int nx, ny, nz;
	    double halfLenght_x, halfLenght_y, halfLenght_z;
	    sscanf(&line[0],"%*s %*s %*s %d %d %d %lf %lf %lf",&nx,&ny,&nz,&halfLenght_x,&halfLenght_y,&halfLenght_z);
	    myMusrScintSD -> SetAPDcellSizes(nx, ny, nz, halfLenght_x, halfLenght_y, halfLenght_z);
	  }
	  else if (strcmp(varName,"SetAPDcellsTimeVariationSigma")==0) {
	    double sigma;
	    sscanf(&line[0],"%*s %*s %*s %lf",&sigma);
	    myMusrScintSD ->SetAPDcellsTimeVariationSigma(sigma*nanosecond);
	  }
	  else if (strcmp(varName,"SetAPDcrossTalk")==0) {
	    double crossTalkProb;
	    sscanf(&line[0],"%*s %*s %*s %lf",&crossTalkProb);
	    myMusrScintSD ->SetAPDcrossTalk(crossTalkProb);
	  }
	  else {
	    G4cout<<"musrDetectorConstruction.cc: ERROR: Unknown parameterName \""
		  <<varName<<"\" ."<<G4endl;
	    ReportGeometryProblem(line);
	  }
	}
      }

      // cks:  Implementation of the Global Field (to allow overlapping fields) based
      //       on the Peter Gumplinger's implementation of G4BeamLine code into Geant4.
      //
      else if (strcmp(tmpString1,"globalfield")==0){
	// ensure the global field is initialized
	// perhaps should be placed at some separate position ?
	(void)F04GlobalField::getObject();

	char typeOfField[100]="Unset";
	double pp1=0, pp2=0, pp3=0;
	sscanf(&line[0],"%*s %*s %*s %lf %lf %lf %s",&pp1,&pp2,&pp3,typeOfField);
	G4ThreeVector position = G4ThreeVector(pp1,pp2,pp3);
        double fieldValue=0.000000001;
	double fieldValueFinal=0;
	int fieldNrOfSteps=0;
	//	if (strcmp(tmpString2,"magnetic")==0){
	if (strcmp(typeOfField,"fromfile")==0) {
	  char fieldInputFileName[100];
	  char fieldTableType[100];
	  char logicalVolumeName[100];
	  sscanf(&line[0],"%*s %*s %*s %*g %*g %*g %*s %s %s %s %lf %lf %d",fieldTableType,fieldInputFileName,logicalVolumeName,
		 &fieldValue,&fieldValueFinal,&fieldNrOfSteps);
	  // Find out the logical volume, to which the field will be placed:
	  G4LogicalVolume* logVol = FindLogicalVolume(logicalVolumeName);
	  if (logVol==NULL) {
	    sprintf(eMessage,"musrDetectorConstruction.cc::Construct(): GLOBAL FIELD: Logical volume \"%s\" not found.",
		    logicalVolumeName);
	    musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
	  }
	  	  
	  // Construct the field
	  musrTabulatedElementField*  myElementTableField = 
	    new musrTabulatedElementField(fieldInputFileName, fieldTableType, fieldValue*tesla, logVol, position);
	  myElementTableField->SetElementFieldName(tmpString2);
	  if (fieldNrOfSteps>0) {
	    //cks The following line might require some correction for the electric field
	    myElementTableField->SetEventNrDependentField(fieldValue*tesla,fieldValueFinal*tesla,fieldNrOfSteps);
	  }
	  //	    FieldList* fields = F04GlobalField::getObject()->getFields();
	  //	    if (fields) {
	  //	      G4cout<<"DEBUG: Detector construction:   fields->size()="<<fields->size()<<G4endl;
	  //	    }
	}

	else if (strcmp(typeOfField,"uniform")==0) {
	  double fieldValue[6];
	  char logicalVolumeName[100];
	  double positionX, positionY, positionZ;
	  G4double half_x = pp1;  // halfwith of the box with the field
	  G4double half_y = pp2;  // halfhight of the box with the field
	  G4double half_z = pp3;  // halflenght of the box with the field

	  sscanf(&line[0],"%*s %*s %*s %*g %*g %*g %*s %lf %lf %lf %s %lf %lf %lf %lf %lf %lf",
		 &positionX, &positionY, &positionZ, logicalVolumeName, 
		 &fieldValue[0],&fieldValue[1],&fieldValue[2],&fieldValue[3],&fieldValue[4],&fieldValue[5]);
	  G4ThreeVector position = G4ThreeVector(positionX,positionY,positionZ);
	  G4LogicalVolume* logVol = FindLogicalVolume(logicalVolumeName);
	  if (logVol==NULL) {
	    sprintf(eMessage,"musrDetectorConstruction.cc::Construct(): GLOBAL FIELD (uniform): Logical volume \"%s\" not found.", logicalVolumeName);
	    musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
	  }
	  G4double fieldValue_tmp[6] = {
	  fieldValue[0]*tesla,        fieldValue[1]*tesla,        fieldValue[2]*tesla,
	  fieldValue[3]*(kilovolt/mm),fieldValue[4]*(kilovolt/mm),fieldValue[5]*(kilovolt/mm)};
	  
	  musrUniformField* myElementUniformField = new musrUniformField(fieldValue_tmp, half_x, half_y, half_z, logVol, position);
	  myElementUniformField->SetElementFieldName(tmpString2);
	}

	else if (strcmp(typeOfField,"quadrupole")==0) {
	  double halfLength, fieldRadius, gradientValue, gradientValueFinal, fringeFactor;
	  int gradientNrOfSteps = 0;
	  char logicalVolumeName[100];
	  sscanf(&line[0],"%*s %*s %*s %*g %*g %*g %*s %lf %lf %lf %s %lf %lf %d",&halfLength,&fieldRadius,&fringeFactor,logicalVolumeName,
		 &gradientValue,&gradientValueFinal,&gradientNrOfSteps);
	  G4LogicalVolume* logVol = FindLogicalVolume(logicalVolumeName);
	  if (logVol==NULL) {
	    sprintf(eMessage,"musrDetectorConstruction.cc::Construct(): GLOBAL FIELD: Logical volume \"%s\" not found.",
		    logicalVolumeName);
	    musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
	  }
	  musrQuadrupole* myMusrQuadrupole = new musrQuadrupole(halfLength*mm,fieldRadius*mm,gradientValue*(tesla/m),fringeFactor,logVol,position);
	  myMusrQuadrupole->SetElementFieldName(tmpString2);
	  if (gradientNrOfSteps>0) {
	    myMusrQuadrupole->SetEventNrDependentField(gradientValue*(tesla/m),gradientValueFinal*(tesla/m),gradientNrOfSteps);
	  }
	}

	else if (strcmp(tmpString2,"setparameter")==0){
	  // First check that the magnetic field already exists:
	  G4FieldManager*      fieldMgr  = G4TransportationManager::GetTransportationManager()->GetFieldManager();
	  G4PropagatorInField* propagMgr = G4TransportationManager::GetTransportationManager()->GetPropagatorInField();
	  if (fieldMgr==NULL) {
	    ReportProblemInStearingFile(line);
	    sprintf(eMessage,"musrDetectorConstruction.cc::Construct(): G4FieldManager not found: fieldMgr=NULL");
	    musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
	  }
	  if (propagMgr==NULL) {
	    ReportProblemInStearingFile(line);
	    sprintf(eMessage,"musrDetectorConstruction.cc::Construct(): G4PropagatorInField not found: propagMgr=NULL");
	    musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,false);
	  }
	  else {
	    char parameterName[100];
	    double parameterValue;
	    sscanf(&line[0],"%*s %*s %*s %s %lf",parameterName,&parameterValue);
	    if (strcmp(parameterName,"SetDeltaIntersection")==0){ fieldMgr->SetDeltaIntersection(parameterValue*mm); }
	    else if (strcmp(parameterName,"SetDeltaOneStep")==0){ fieldMgr->SetDeltaOneStep(parameterValue*mm); }
	    else if (strcmp(parameterName,"SetMinimumEpsilonStep")==0){ fieldMgr->SetMinimumEpsilonStep(parameterValue); }
	    else if (strcmp(parameterName,"SetMaximumEpsilonStep")==0){ fieldMgr->SetMaximumEpsilonStep(parameterValue); }
	    else if (strcmp(parameterName,"SetLargestAcceptableStep")==0) { propagMgr->SetLargestAcceptableStep(parameterValue*mm); }
	    else if (strcmp(parameterName,"SetMaxLoopCount")==0) {propagMgr->SetMaxLoopCount(int(parameterValue)); }
	    else {
	      G4cout<<"musrDetectorConstruction.cc: ERROR: Unknown parameterName \""
		    <<parameterName<<"\" ."<<G4endl;
	      ReportGeometryProblem(line);
	    }
	  }
	}

	else if (strcmp(tmpString2,"printparameters")==0){    // Print the accuracy parameters for the magnetic field
	  G4FieldManager* fieldMgr = G4TransportationManager::GetTransportationManager()->GetFieldManager();
	  G4PropagatorInField* propagMgr = G4TransportationManager::GetTransportationManager()->GetPropagatorInField();
	  if (fieldMgr==NULL) {
	    G4cout<<"musrDetectorConstruction: ERROR: Field manager not found!"<<G4endl;
	    G4cout<<"                          Can not print the accuracy parameters of the magnetic field."<<G4endl;
	  }
	  else { 
	    G4cout<<"GetDeltaIntersection()    = "<<fieldMgr->GetDeltaIntersection()/mm<<" mm"<<G4endl;
	    G4cout<<"GetDeltaOneStep()         = "<<fieldMgr->GetDeltaOneStep()/mm<<" mm"<<G4endl;
	    G4cout<<"GetMinimumEpsilonStep()   = "<<fieldMgr->GetMinimumEpsilonStep()<<G4endl;
	    G4cout<<"GetMaximumEpsilonStep()   = "<<fieldMgr->GetMaximumEpsilonStep()<<G4endl;
	  }

	  if (propagMgr==NULL) {
	    G4cout<<"musrDetectorConstruction: ERROR: G4PropagatorInField not found!"<<G4endl;
	    G4cout<<"                          Can not print the accuracy parameters of the magnetic field."<<G4endl;
	  }
	  else {
	    G4cout<<"GetLargestAcceptableStep()= "<<propagMgr->GetLargestAcceptableStep()/mm<<" mm"<<G4endl;
	    G4cout<<"GetMaxLoopCount()         = "<<propagMgr->GetMaxLoopCount()<<G4endl;
	  }	    
	}

	else if ((strcmp(tmpString2,"printFieldValueAtPoint")==0)||(strcmp(tmpString2,"printFieldDerivativeAtPoint")==0)) {    // Print the fieldvalue at the given point
	  double p0, p1, p2;
	  sscanf(&line[0],"%*s %*s %*s %lf %lf %lf",&p0,&p1,&p2);
	  if (F04GlobalField::Exists()) {
	    F04GlobalField* myGlobalField = F04GlobalField::getObject();
	    if (myGlobalField) {
	      // The global field is not properly initialised at this point.  Therefore the points have to
              // be stored in  "F04GlobalField" object  and printed later on in musrRunAction.cc .
	      if (strcmp(tmpString2,"printFieldValueAtPoint")==0)       myGlobalField->AddPointForFieldTesting(G4ThreeVector(p0,p1,p2));
	      if (strcmp(tmpString2,"printFieldDerivativeAtPoint")==0)  myGlobalField->AddPointForFieldDerivativeTesting(G4ThreeVector(p0,p1,p2));
	    }
	    else {
	      sprintf(eMessage,"musrDetectorConstruction.cc::Construct(): printFieldValueAtPoint requested, but field not found");
	      musrErrorMessage::GetInstance()->musrError(SERIOUS,eMessage,false);
	    }
	  }
	}
	
	else {ReportGeometryProblem(line);}
      }
      
      
      //   Set range cut for a given volume, if requested by the macro file
      else if (strcmp(tmpString1,"SetUserLimits")==0){
	G4LogicalVolume* pLogVol = FindLogicalVolume(tmpString2);
	if (pLogVol==NULL) {
	  G4cout << "ERROR! musrDetectorConstruction::Construct():  SetUserLimits: Logical Volume \""
		 << tmpString2 <<"\" not found!"<<G4endl<<"S T O P    F O R C E D"<<G4endl;
	  ReportGeometryProblem(line);
	}

	double ustepMax = -1;
	double utrakMax = -1;
	double utimeMax = -1;
	double uekinMin = -1;
	double urangMin = -1;
	sscanf(&line[0],"%*s %*s %*s %lf %lf %lf %lf %lf", &ustepMax, &utrakMax, &utimeMax, &uekinMin, &urangMin);
	G4UserLimits* myUserLimits = new G4UserLimits();
	G4cout<<"musrDetectorConstruction.cc:  G4UserLimits in "<<tmpString2<<": ";
	if (ustepMax>0) {myUserLimits->SetMaxAllowedStep(ustepMax*mm);    G4cout<<"ustepMax = "<<ustepMax<<" mm, ";}
	if (utrakMax>0) {myUserLimits->SetUserMaxTrackLength(utrakMax*mm);G4cout<<"utrakMax = "<<utrakMax<<" mm, ";}
 	if (utimeMax>0) {myUserLimits->SetUserMaxTime(utimeMax*ns);       G4cout<<"utimeMax = "<<utimeMax<<" ns, ";}
 	if (uekinMin>0) {myUserLimits->SetUserMinEkine(uekinMin*MeV);     G4cout<<"uekinMin = "<<uekinMin<<" MeV, ";}
 	if (urangMin>0) {myUserLimits->SetUserMinRange(urangMin*mm);      G4cout<<"urangMin = "<<urangMin<<" mm, ";}
	G4cout<<G4endl;
	pLogVol->SetUserLimits(myUserLimits);
      }


      else if (strcmp(tmpString1,"rootOutputDirectoryName")==0){
	char rootOutDirName[1000];
	sscanf(&line[0],"%*s %*s %s",rootOutDirName);
	// Cut out the character '/' at the end of the directory name, if it was specified in the name
	if (rootOutDirName[strlen(rootOutDirName)-1]=='/') rootOutDirName[strlen(rootOutDirName)-1]='\0';
	myRootOutput->setRootOutputDirectoryName(rootOutDirName);
      }
	
      else if (strcmp(tmpString1,"storeOnlyEventsWithHitInDetID")==0){
	G4int variable;
	sscanf(&line[0],"%*s %*s %d",&variable);
	if (variable!=0){ 
	  musrParameters::storeOnlyEventsWithHits = true;
	  musrParameters::storeOnlyEventsWithHitInDetID = variable;
	  char eMessage[200];
	  sprintf(eMessage,
		  "musrDetectorConstruction.cc:: Only the events with at least one hit in the detector ID=%d are stored",
		  variable);
	  musrErrorMessage::GetInstance()->musrError(INFO,eMessage,false);
	}
      } 

      else if (strcmp(tmpString1,"storeOnlyEventsWithMuonsDecayedInDetID")==0){
	G4int variable;
	sscanf(&line[0],"%*s %*s %d",&variable);
	if (variable!=0){ 
	  musrParameters::storeOnlyEventsWithMuonsDecayedInDetID = variable;
	  char eMessage[200];
	  sprintf(eMessage,
		  "musrDetectorConstruction.cc:: Only the events, in which muon stop in the detector ID=%d, are stored",
		  variable);
	  musrErrorMessage::GetInstance()->musrError(INFO,eMessage,false);
	}
      } 

      else if (strcmp(tmpString1,"storeOnlyEventsWithHits")==0){
	if (strcmp(tmpString2,"false")==0){ musrParameters::storeOnlyEventsWithHits = false; }
      } 

      else if (strcmp(tmpString1,"storeOnlyTheFirstTimeHit")==0){
	if (strcmp(tmpString2,"true")==0){ musrParameters::storeOnlyTheFirstTimeHit = true; }
      } 

      else if (strcmp(tmpString1,"killAllElectrons")==0){
	if (strcmp(tmpString2,"true")==0){ musrParameters::killAllElectrons = true; }
	else                             { musrParameters::killAllElectrons = false; }
      } 
      
      else if (strcmp(tmpString1,"killAllPositrons")==0){
	if (strcmp(tmpString2,"true")==0){ musrParameters::killAllPositrons = true; }
	else                             { musrParameters::killAllPositrons = false; }
      } 

      else if (strcmp(tmpString1,"killAllGammas")==0){
	if (strcmp(tmpString2,"true")==0){ musrParameters::killAllGammas = true; }
	else                             { musrParameters::killAllGammas = false; }
      } 

      else if (strcmp(tmpString1,"killAllNeutrinos")==0){
	if (strcmp(tmpString2,"true")==0){ musrParameters::killAllNeutrinos = true;  }
	else                             { musrParameters::killAllNeutrinos = false; }
      } 
      
      else if (strcmp(tmpString1,"maximumTimePerEvent")==0){
	int variable;
	sscanf(&line[0],"%*s %*s %d",&variable);
	if (variable>0){ 
	  musrParameters::maximumTimePerEvent = variable;
	}
      }

      else if (strcmp(tmpString1,"maximumNrOfStepsPerTrack")==0){
	int variable;
	sscanf(&line[0],"%*s %*s %d",&variable);
	if (variable>0){ 
	  musrParameters::maximumNrOfStepsPerTrack = variable;
	}
      }

      else if (strcmp(tmpString1,"getDetectorMass")==0){
	G4LogicalVolume* massVol = FindLogicalVolume(tmpString2);
	if (massVol==NULL) {
	  G4cout << "ERROR! musrDetectorConstruction::Construct():   Logical Volume \""
		 << tmpString3 <<"\" not found!"<<G4endl<<"S T O P    F O R C E D"<<G4endl;
	  ReportGeometryProblem(line);
	}
	G4cout<<"Mass of the detector "<<tmpString2<<" is "<<massVol->GetMass()/kg<<" kg."<<G4endl;
      }
      

      else if (strcmp(tmpString1,"signalSeparationTime")==0){
	double timeSeparation;
	sscanf(&line[0],"%*s %*s %lf",&timeSeparation);
        musrParameters::signalSeparationTime = timeSeparation*nanosecond;
      }

      else if (strcmp(tmpString1,"maximumRunTimeAllowed")==0){   // in seconds
	double timeMax;
	sscanf(&line[0],"%*s %*s %lf",&timeMax);
        musrEventAction::maximumRunTimeAllowed = timeMax;
      }
 

      else if (strcmp(tmpString1,"logicalVolumeToBeReweighted")==0){
	if (strcmp(tmpString2,"mu")==0) { 
	  int eventWeight;
	  char tmpLogVolName[100];
	  sscanf(&line[0],"%*s %*s %*s %s %d",tmpLogVolName,&eventWeight);
	  mySteppingAction -> SetVolumeForMuonEventReweighting(G4String(tmpLogVolName),eventWeight);
	}
	else {
	  sprintf(eMessage,
		  "musrDetectorConstruction.cc:: logicalVolumeToBeReweighted - reweighting for particle %s not yet implemented",
		  tmpString2);
	  musrErrorMessage::GetInstance()->musrError(FATAL,eMessage,true);
	}
      }

      // Set G4Regions - intended mainly for the coulomb scattering or special production cuts  (added on 2008.08.21)
      else if (strcmp(tmpString1,"region")==0) {
	if (strcmp(tmpString2,"define")==0) {
	  char charRegionName[100];
	  char charLogicalVolumeName[100];
	  sscanf(&line[0],"%*s %*s %*s %s %s",charRegionName,charLogicalVolumeName);
	  G4String regionName = charRegionName;
	  G4String logicalVolumeName = charLogicalVolumeName;

	  G4Region* myRegion = G4RegionStore::GetInstance()->GetRegion(regionName,false);
	  if( myRegion == NULL )  { // First time - instantiate a region and a cut objects
	    myRegion = new G4Region(regionName);
	    G4cout<<"musrDetectorConstruction:  G4Region "<<regionName<<" newly created, ";
	    G4ProductionCuts*  cuts = new G4ProductionCuts();
	    myRegion->SetProductionCuts(cuts);
	  }
	  else {G4cout<<"musrDetectorConstruction:  G4Region "<<regionName<<" already exists,";}
	  //	  else  { // Second time - get a cut object from region
	  //        cuts = fRegGasDet->GetProductionCuts();
	  //      }
	  G4LogicalVolume* logicalVolume = FindLogicalVolume(logicalVolumeName);
	  if (logicalVolume != NULL) {
	    myRegion->AddRootLogicalVolume(logicalVolume);
	    G4cout<<" and volume "<<logicalVolumeName<<" assigned to it."<<G4endl;
	  }
	  else {
	    G4cout<<G4endl;
	    sprintf(eMessage,
		  "musrDetectorConstruction.cc:: logicalVolume %s not found when requesting its association with the G4Region %s.",
		    charLogicalVolumeName,charRegionName);
	    musrErrorMessage::GetInstance()->musrError(SERIOUS,eMessage,false);
	  }
	}
	else if (strcmp(tmpString2,"setProductionCut")==0) {
	  char charRegionName[100];
	  double fGammaCut=0, fElectronCut=0, fPositronCut=0;
	  sscanf(&line[0],"%*s %*s %*s %s %lf %lf %lf",charRegionName,&fGammaCut,&fElectronCut,&fPositronCut);
	  G4String regionName = charRegionName;
	  G4Region* myRegion = G4RegionStore::GetInstance()->GetRegion(regionName,false);
	  if( myRegion == NULL )  { // G4Region does not exist 
	    G4cout<<"musrDetectorConstruction:  setProductionCut required for the G4Region "<<regionName<<","<<G4endl;
	    G4cout<<"         however this G4Region has not been defined yet.  Please correct the steering file."<<G4endl;
	    G4cout << "S T O P    F O R C E D"<<G4endl;
	    ReportGeometryProblem(line);
	    //    cuts = new G4ProductionCuts();
	    //    myRegion->SetProductionCuts(cuts);
	  }
	  else {  // G4Region exists, so set the cuts:
	    G4ProductionCuts* cuts = myRegion->GetProductionCuts();
	    if (cuts==NULL) {G4cout<<"musrDetectorConstruction: DEBUG - ERROR !!!!  cuts for G4Region not defined!!!!"<<G4endl;}
	    else {
	      if (fGammaCut!=0) cuts->SetProductionCut(fGammaCut,"gamma");
	      if (fElectronCut!=0) cuts->SetProductionCut(fElectronCut,"e-");
	      if (fPositronCut!=0) cuts->SetProductionCut(fPositronCut,"e+");
	    }
	  }
	}
	else {
	  G4cout << "ERROR! musrDetectorConstruction::Construct():   Unknown command requested for the \"region\" keyword."<<G4endl;
	  G4cout << "S T O P    F O R C E D"<<G4endl;
	  ReportGeometryProblem(line);
	}
      }


      //  Set the variables which the user does not want to store in the output root file.
      else if (strcmp(tmpString1,"rootOutput")==0){
	char storeIt[100];
	sscanf(&line[0],"%*s %*s %*s %s",storeIt);
	if (strcmp(storeIt,"off")==0) {
	  if (strcmp(tmpString2,"runID")==0)        {musrRootOutput::store_runID = false;}
	  if (strcmp(tmpString2,"eventID")==0)      {musrRootOutput::store_eventID = false;}
	  if (strcmp(tmpString2,"weight")==0)       {musrRootOutput::store_weight = false;}
	  if (strcmp(tmpString2,"BFieldAtDecay")==0){musrRootOutput::store_BFieldAtDecay = false;}
	  if (strcmp(tmpString2,"muIniTime")==0)    {musrRootOutput::store_muIniTime = false;}
	  if (strcmp(tmpString2,"muIniPosX")==0)    {musrRootOutput::store_muIniPosX = false;}
	  if (strcmp(tmpString2,"muIniPosY")==0)    {musrRootOutput::store_muIniPosY = false;}
	  if (strcmp(tmpString2,"muIniPosZ")==0)    {musrRootOutput::store_muIniPosZ = false;}
	  if (strcmp(tmpString2,"muIniMomX")==0)    {musrRootOutput::store_muIniMomX = false;}
	  if (strcmp(tmpString2,"muIniMomY")==0)    {musrRootOutput::store_muIniMomY = false;}
	  if (strcmp(tmpString2,"muIniMomZ")==0)    {musrRootOutput::store_muIniMomZ = false;}
	  if (strcmp(tmpString2,"muIniPolX")==0)    {musrRootOutput::store_muIniPolX = false;}
	  if (strcmp(tmpString2,"muIniPolY")==0)    {musrRootOutput::store_muIniPolY = false;}
	  if (strcmp(tmpString2,"muIniPolZ")==0)    {musrRootOutput::store_muIniPolZ = false;}
	  if (strcmp(tmpString2,"muDecayDetID")==0) {musrRootOutput::store_muDecayDetID = false;}
	  if (strcmp(tmpString2,"muDecayPosX")==0)  {musrRootOutput::store_muDecayPosX = false;}
	  if (strcmp(tmpString2,"muDecayPosY")==0)  {musrRootOutput::store_muDecayPosY = false;}
	  if (strcmp(tmpString2,"muDecayPosZ")==0)  {musrRootOutput::store_muDecayPosZ = false;}
	  if (strcmp(tmpString2,"muDecayTime")==0)  {musrRootOutput::store_muDecayTime = false;}
	  if (strcmp(tmpString2,"muDecayPolX")==0)  {musrRootOutput::store_muDecayPolX = false;}
	  if (strcmp(tmpString2,"muDecayPolY")==0)  {musrRootOutput::store_muDecayPolY = false;}
	  if (strcmp(tmpString2,"muDecayPolZ")==0)  {musrRootOutput::store_muDecayPolZ = false;}
	  if (strcmp(tmpString2,"muTargetTime")==0) {musrRootOutput::store_muTargetTime = false;}
	  if (strcmp(tmpString2,"muTargetPolX")==0) {musrRootOutput::store_muTargetPolX = false;}
	  if (strcmp(tmpString2,"muTargetPolY")==0) {musrRootOutput::store_muTargetPolY = false;}
	  if (strcmp(tmpString2,"muTargetPolZ")==0) {musrRootOutput::store_muTargetPolZ = false;}
	  if (strcmp(tmpString2,"muTargetMomX")==0) {musrRootOutput::store_muTargetMomX = false;}
	  if (strcmp(tmpString2,"muTargetMomY")==0) {musrRootOutput::store_muTargetMomY = false;}
	  if (strcmp(tmpString2,"muTargetMomZ")==0) {musrRootOutput::store_muTargetMomZ = false;}
	  if (strcmp(tmpString2,"muM0Time")==0)     {musrRootOutput::store_muM0Time = false;}
	  if (strcmp(tmpString2,"muM0PolX")==0)     {musrRootOutput::store_muM0PolX = false;}
	  if (strcmp(tmpString2,"muM0PolY")==0)     {musrRootOutput::store_muM0PolY = false;}
	  if (strcmp(tmpString2,"muM0PolZ")==0)     {musrRootOutput::store_muM0PolZ = false;}
	  if (strcmp(tmpString2,"muM1Time")==0)     {musrRootOutput::store_muM1Time = false;}
	  if (strcmp(tmpString2,"muM1PolX")==0)     {musrRootOutput::store_muM1PolX = false;}
	  if (strcmp(tmpString2,"muM1PolY")==0)     {musrRootOutput::store_muM1PolY = false;}
	  if (strcmp(tmpString2,"muM1PolZ")==0)     {musrRootOutput::store_muM1PolZ = false;}
	  if (strcmp(tmpString2,"muM2Time")==0)     {musrRootOutput::store_muM2Time = false;}
	  if (strcmp(tmpString2,"muM2PolX")==0)     {musrRootOutput::store_muM2PolX = false;}
	  if (strcmp(tmpString2,"muM2PolY")==0)     {musrRootOutput::store_muM2PolY = false;}
	  if (strcmp(tmpString2,"muM2PolZ")==0)     {musrRootOutput::store_muM2PolZ = false;}
	  if (strcmp(tmpString2,"posIniMomX")==0)   {musrRootOutput::store_posIniMomX = false;}
	  if (strcmp(tmpString2,"posIniMomY")==0)   {musrRootOutput::store_posIniMomY = false;}
	  if (strcmp(tmpString2,"posIniMomZ")==0)   {musrRootOutput::store_posIniMomZ = false;}
	  if (strcmp(tmpString2,"nOptPhot")==0)     {musrRootOutput::store_nOptPhot   = false;}
	  if (strcmp(tmpString2,"nOptPhotDet")==0)  {musrRootOutput::store_nOptPhotDet = false;}
	  if (strcmp(tmpString2,"fieldNomVal")==0)  {musrRootOutput::store_fieldNomVal = false;}
	  if (strcmp(tmpString2,"det_ID")==0)       {musrRootOutput::store_det_ID = false;}
	  if (strcmp(tmpString2,"det_edep")==0)     {musrRootOutput::store_det_edep = false;}
	  if (strcmp(tmpString2,"det_edep_el")==0)  {musrRootOutput::store_det_edep_el = false;}
	  if (strcmp(tmpString2,"det_edep_pos")==0) {musrRootOutput::store_det_edep_pos = false;}
	  if (strcmp(tmpString2,"det_edep_gam")==0) {musrRootOutput::store_det_edep_gam = false;}
	  if (strcmp(tmpString2,"det_edep_mup")==0) {musrRootOutput::store_det_edep_mup = false;}
	  if (strcmp(tmpString2,"det_nsteps")==0)   {musrRootOutput::store_det_nsteps = false;}
	  if (strcmp(tmpString2,"det_length")==0)   {musrRootOutput::store_det_length = false;}
	  if (strcmp(tmpString2,"det_start")==0)    {musrRootOutput::store_det_start = false;}
	  if (strcmp(tmpString2,"det_end")==0)      {musrRootOutput::store_det_end = false;}
	  if (strcmp(tmpString2,"det_x")==0)        {musrRootOutput::store_det_x = false;}
	  if (strcmp(tmpString2,"det_y")==0)        {musrRootOutput::store_det_y = false;}
	  if (strcmp(tmpString2,"det_z")==0)        {musrRootOutput::store_det_z = false;}
	  if (strcmp(tmpString2,"det_kine")==0)	    {musrRootOutput::store_det_kine = false;}
	  if (strcmp(tmpString2,"det_VrtxKine")==0) {musrRootOutput::store_det_VrtxKine = false;}
	  if (strcmp(tmpString2,"det_VrtxX")==0)    {musrRootOutput::store_det_VrtxX = false;}
	  if (strcmp(tmpString2,"det_VrtxY")==0)    {musrRootOutput::store_det_VrtxY = false;}
	  if (strcmp(tmpString2,"det_VrtxZ")==0)    {musrRootOutput::store_det_VrtxZ = false;}
	  if (strcmp(tmpString2,"det_VrtxVolID")==0){musrRootOutput::store_det_VrtxVolID = false;}
	  if (strcmp(tmpString2,"det_VrtxProcID")==0){musrRootOutput::store_det_VrtxProcID = false;}
	  if (strcmp(tmpString2,"det_VrtxTrackID")==0){musrRootOutput::store_det_VrtxTrackID = false;}
	  if (strcmp(tmpString2,"det_VrtxParticleID")==0){musrRootOutput::store_det_VrtxParticleID = false;}
	  if (strcmp(tmpString2,"det_VvvKine")==0)  {musrRootOutput::store_det_VvvKine = false;}
	  if (strcmp(tmpString2,"det_VvvX")==0)     {musrRootOutput::store_det_VvvX = false;}
	  if (strcmp(tmpString2,"det_VvvY")==0)     {musrRootOutput::store_det_VvvY = false;}
	  if (strcmp(tmpString2,"det_VvvZ")==0)     {musrRootOutput::store_det_VvvZ = false;}
	  if (strcmp(tmpString2,"det_VvvVolID")==0) {musrRootOutput::store_det_VvvVolID = false;}
	  if (strcmp(tmpString2,"det_VvvProcID")==0){musrRootOutput::store_det_VvvProcID = false;}
	  if (strcmp(tmpString2,"det_VvvTrackID")==0){musrRootOutput::store_det_VvvTrackID = false;}
	  if (strcmp(tmpString2,"det_VvvParticleID")==0){musrRootOutput::store_det_VvvParticleID = false;}
	  if (strcmp(tmpString2,"odet_ID")==0)       {musrRootOutput::store_odet_ID = false;}
	  if (strcmp(tmpString2,"odet_nPhot")==0)    {musrRootOutput::store_odet_nPhot = false;}
	  if (strcmp(tmpString2,"odet_nPhotPrim")==0) {musrRootOutput::store_odet_nPhotPrim = false;}
	  if (strcmp(tmpString2,"odet_timeFirst")==0) {musrRootOutput::store_odet_timeFirst = false;}
	  if (strcmp(tmpString2,"odet_timeSecond")==0) {musrRootOutput::store_odet_timeSecond = false;}
	  if (strcmp(tmpString2,"odet_timeThird")==0) {musrRootOutput::store_odet_timeThird = false;}
	  if (strcmp(tmpString2,"odet_timeA")==0)    {musrRootOutput::store_odet_timeA = false;}
	  if (strcmp(tmpString2,"odet_timeB")==0)    {musrRootOutput::store_odet_timeB = false;}
	  if (strcmp(tmpString2,"odet_timeC")==0)    {musrRootOutput::store_odet_timeC = false;}
	  if (strcmp(tmpString2,"odet_timeD")==0)    {musrRootOutput::store_odet_timeD = false;}
	  if (strcmp(tmpString2,"odet_timeMean")==0) {musrRootOutput::store_odet_timeMean = false;}
	  if (strcmp(tmpString2,"odet_timeLast")==0) {musrRootOutput::store_odet_timeLast = false;}
	  if (strcmp(tmpString2,"odet_timeCFD")==0)  {musrRootOutput::store_odet_timeCFD = false;}
	  if (strcmp(tmpString2,"odet_amplCFD")==0)  {musrRootOutput::store_odet_amplCFD = false;}
	}
	else if(strcmp(storeIt,"on")==0) {
	  if (strcmp(tmpString2,"fieldIntegralBx")==0){musrRootOutput::store_fieldIntegralBx = true;}
	  if (strcmp(tmpString2,"fieldIntegralBy")==0){musrRootOutput::store_fieldIntegralBy = true;}
	  if (strcmp(tmpString2,"fieldIntegralBz")==0){musrRootOutput::store_fieldIntegralBz = true;}
	  if (strcmp(tmpString2,"fieldIntegralBz1")==0){musrRootOutput::store_fieldIntegralBz1 = true;}
	  if (strcmp(tmpString2,"fieldIntegralBz2")==0){musrRootOutput::store_fieldIntegralBz2 = true;}
	  if (strcmp(tmpString2,"fieldIntegralBz3")==0){musrRootOutput::store_fieldIntegralBz3 = true;}
	  if (strcmp(tmpString2,"odet_timeCFDarray")==0){musrRootOutput::store_odet_timeCFDarray = true;}
	  if (strcmp(tmpString2,"odet_timeC1")==0)     {musrRootOutput::store_odet_timeC1 = true;}
	  if (strcmp(tmpString2,"phot_time")==0)     {musrRootOutput::store_phot_time = true;}
	  if ((musrRootOutput::store_fieldIntegralBx)||(musrRootOutput::store_fieldIntegralBy)||
	      (musrRootOutput::store_fieldIntegralBz)||(musrRootOutput::store_fieldIntegralBz1)||
	      (musrRootOutput::store_fieldIntegralBz2)||(musrRootOutput::store_fieldIntegralBz3) ) {
	    mySteppingAction -> SetCalculationOfFieldIntegralRequested(true);
	  }
	}
      }
      
      else if ((strcmp(tmpString1,"process")==0)||(strcmp(tmpString1,"G4OpticalPhotons")==0)||(strcmp(tmpString1,"G4OpticalPhotonsUnprocess")==0)
	       ||(strcmp(tmpString1,"materialPropertiesTable")==0)||(strcmp(tmpString1,"setMaterialPropertiesTable")==0)) {
	;  // processes are interpreded later in  musrPhysicsList.cc
      }


      else ReportGeometryProblem(line);
      
    }
  }
  fclose(fSteeringFile);
  //  G4cout<< "musrDetectorConstruction.cc:  pointerToWorldVolume="<<pointerToWorldVolume<<G4endl;
  return pointerToWorldVolume;
}


void musrDetectorConstruction::DefineMaterials()
{

//--------- Material definitions ---------
  G4double a, z, density;  // a = mass of a mole,   z = mean number of protons;

  G4int ncomponents, natoms;
  G4double  fractionmass;

  G4NistManager* man = G4NistManager::Instance();
  
  //
  // define Elements
  //
  G4Element* H = man->FindOrBuildElement("H");
  G4Element* C = man->FindOrBuildElement("C");
  G4Element* N = man->FindOrBuildElement("N");
  G4Element* O = man->FindOrBuildElement("O");
  // Elements required for Brass
  G4Element* Cu = man->FindOrBuildElement("Cu");
  G4Element* Zn = man->FindOrBuildElement("Zn");
  // elements required for Stainless Steel
  G4Element* Cr = man->FindOrBuildElement("Cr");
  G4Element* Fe = man->FindOrBuildElement("Fe");
  G4Element* Ni = man->FindOrBuildElement("Ni");
 // Elements required for MCPglass
  G4Element* Pb = man->FindOrBuildElement("Pb"); 
  G4Element* Si = man->FindOrBuildElement("Si"); 
  G4Element* K  = man->FindOrBuildElement("K" ); 
  G4Element* Rb = man->FindOrBuildElement("Rb"); 
  G4Element* Ba = man->FindOrBuildElement("Ba"); 
  G4Element* As = man->FindOrBuildElement("As"); 
  G4Element* Cs = man->FindOrBuildElement("Cs"); 
  G4Element* Na = man->FindOrBuildElement("Na"); 
  
  // Elements required for Macor
  G4Element* B  = man->FindOrBuildElement("B" );
  G4Element* Al = man->FindOrBuildElement("Al");
  G4Element* Mg = man->FindOrBuildElement("Mg");

  // compounds required for MCP Macor
  G4Material* MgO = new G4Material("MgO", 3.60*g/cm3, ncomponents=2);
  MgO->AddElement(Mg, natoms=1);
  MgO->AddElement(O,  natoms=1);

  G4Material* SiO2 = new G4Material("SiO2", 2.533*g/cm3, ncomponents=2); // quartz
  SiO2->AddElement(O,  natoms=2);
  SiO2->AddElement(Si, natoms=1);

  G4Material* Al2O3 = new G4Material("Al2O3", 3.985*g/cm3, ncomponents=2); // saphire
  Al2O3->AddElement (Al, natoms=2);
  Al2O3->AddElement (O,  natoms=3);
 
  G4Material* K2O = new G4Material("K2O", 2.350*g/cm3, ncomponents=2);
  K2O->AddElement(O, natoms=1);
  K2O->AddElement(K, natoms=2);
  
  G4Material* B2O3 = new G4Material("B2O3", 2.550*g/cm3, ncomponents=2);
  B2O3->AddElement (B, natoms=2);
  B2O3->AddElement (O, natoms=3);

  G4Material* Sci = 
    new G4Material("Scintillator", density= 1.032*g/cm3, ncomponents=2);
  Sci->AddElement(C, natoms=9);
  Sci->AddElement(H, natoms=10);

  G4Material* Myl = 
    new G4Material("Mylar", density= 1.397*g/cm3, ncomponents=3);
  Myl->AddElement(C, natoms=10);
  Myl->AddElement(H, natoms= 8);
  Myl->AddElement(O, natoms= 4);

  // Brass
  G4Material* brass = new G4Material("Brass", density= 8.40*g/cm3, ncomponents=2);
  brass -> AddElement(Zn, fractionmass = 30*perCent);
  brass -> AddElement(Cu, fractionmass = 70*perCent);

  // Stainless steel
  G4Material* steel = new G4Material("Steel", density= 7.93*g/cm3, ncomponents=3);
  steel->AddElement(Ni, fractionmass=0.11);
  steel->AddElement(Cr, fractionmass=0.18);
  steel->AddElement(Fe, fractionmass=0.71);

  G4Material* macor= // Macor (used in the MCP detector)
    new G4Material("Macor", density=2.52*g/cm3, ncomponents=5);
  macor->AddMaterial(SiO2, fractionmass=0.470); // quartz
  macor->AddMaterial(MgO,  fractionmass=0.180);
  macor->AddMaterial(Al2O3,fractionmass=0.170); // saphire
  macor->AddMaterial(K2O,  fractionmass=0.105);
  macor->AddMaterial(B2O3, fractionmass=0.075);
    
  G4Material* mcpglass = // Glass of the Multi Channel Plate
    new G4Material("MCPglass", density=2.0*g/cm3, ncomponents=9);
  mcpglass->AddElement(Pb, fractionmass= 0.480);
  mcpglass->AddElement(O,  fractionmass= 0.258);
  mcpglass->AddElement(Si, fractionmass= 0.182);
  mcpglass->AddElement(K,  fractionmass= 0.042);
  mcpglass->AddElement(Rb, fractionmass= 0.018);
  mcpglass->AddElement(Ba, fractionmass= 0.013);
  mcpglass->AddElement(As, fractionmass= 0.004);
  mcpglass->AddElement(Cs, fractionmass= 0.002);
  mcpglass->AddElement(Na, fractionmass= 0.001);

//
// define a material from elements.   case 2: mixture by fractional mass
//

  G4Material* Air = 
    new G4Material("Air"  , density= 1.290*mg/cm3, ncomponents=2);
  Air->AddElement(N, fractionmass=0.7);
  Air->AddElement(O, fractionmass=0.3);

  G4Material* Air1mbar = 
    new G4Material("Air1mbar"  , density= 1.290e-3*mg/cm3, ncomponents=2);
  Air1mbar->AddElement(N, fractionmass=0.7);
  Air1mbar->AddElement(O, fractionmass=0.3);

  G4Material* AirE1mbar = 
    new G4Material("AirE1mbar"  , density= 1.290e-4*mg/cm3, ncomponents=2);
  AirE1mbar->AddElement(N, fractionmass=0.7);
  AirE1mbar->AddElement(O, fractionmass=0.3);

  G4Material* AirE2mbar = 
    new G4Material("AirE2mbar"  , density= 1.290e-5*mg/cm3, ncomponents=2);
  AirE2mbar->AddElement(N, fractionmass=0.7);
  AirE2mbar->AddElement(O, fractionmass=0.3);

  G4Material* AirE3mbar = 
    new G4Material("AirE3mbar"  , density= 1.290e-6*mg/cm3, ncomponents=2);
  AirE3mbar->AddElement(N, fractionmass=0.7);
  AirE3mbar->AddElement(O, fractionmass=0.3);

  G4Material* AirE4mbar = 
    new G4Material("AirE4mbar"  , density= 1.290e-7*mg/cm3, ncomponents=2);
  AirE4mbar->AddElement(N, fractionmass=0.7);
  AirE4mbar->AddElement(O, fractionmass=0.3);

  G4Material* AirE5mbar = 
    new G4Material("AirE5mbar"  , density= 1.290e-8*mg/cm3, ncomponents=2);
  AirE5mbar->AddElement(N, fractionmass=0.7);
  AirE5mbar->AddElement(O, fractionmass=0.3);

  G4Material* AirE6mbar = 
    new G4Material("AirE6mbar"  , density= 1.290e-9*mg/cm3, ncomponents=2);
  AirE6mbar->AddElement(N, fractionmass=0.7);
  AirE6mbar->AddElement(O, fractionmass=0.3);

//
// examples of vacuum
//

//  G4Material* Vacuum =
  new G4Material("Vacuum", z=1., a=1.01*g/mole,density= universe_mean_density,
		   kStateGas, 2.73*kelvin, 3.e-18*pascal);
  
  new G4Material("ArgonGas", z= 18., a= 39.95*g/mole, density= 0.00000000001*mg/cm3);

  new G4Material("HeliumGas5mbar", z=2., a=4.002602*g/mole, density= 0.00000088132*g/cm3);
  new G4Material("HeliumGas6mbar", z=2., a=4.002602*g/mole, density= 0.000001057584*g/cm3);
  new G4Material("HeliumGas7mbar", z=2., a=4.002602*g/mole, density= 0.000001233848*g/cm3);
  new G4Material("HeliumGas8mbar", z=2., a=4.002602*g/mole, density= 0.000001410112*g/cm3);
  new G4Material("HeliumGas9mbar", z=2., a=4.002602*g/mole, density= 0.000001586376*g/cm3);
  new G4Material("HeliumGas10mbar",z=2., a=4.002602*g/mole, density= 0.00000176264*g/cm3);
  new G4Material("HeliumGas11mbar",z=2., a=4.002602*g/mole, density= 0.000001938904*g/cm3);
  new G4Material("HeliumGas12mbar",z=2., a=4.002602*g/mole, density= 0.000002115168*g/cm3);
  new G4Material("HeliumGas13mbar",z=2., a=4.002602*g/mole, density= 0.000002291432*g/cm3);
  new G4Material("HeliumGas14mbar",z=2., a=4.002602*g/mole, density= 0.000002467696*g/cm3);
  new G4Material("HeliumGas15mbar",z=2., a=4.002602*g/mole, density= 0.00000264396*g/cm3);
  new G4Material("HeliumGas20mbar",z=2., a=4.002602*g/mole, density= 0.00000352528*g/cm3);
  new G4Material("HeliumGas30mbar",z=2., a=4.002602*g/mole, density= 0.00000528792*g/cm3);
  new G4Material("HeliumGas40mbar",z=2., a=4.002602*g/mole, density= 0.00000705056*g/cm3);
  new G4Material("HeliumGas50mbar",z=2., a=4.002602*g/mole, density= 0.00000881320*g/cm3);
  new G4Material("HeliumGas60mbar",z=2., a=4.002602*g/mole, density= 0.00001057584*g/cm3);
  new G4Material("HeliumGas70mbar",z=2., a=4.002602*g/mole, density= 0.00001233848*g/cm3);
  new G4Material("HeliumGas80mbar",z=2., a=4.002602*g/mole, density= 0.00001410112*g/cm3);
  new G4Material("HeliumGas90mbar",z=2., a=4.002602*g/mole, density= 0.00001586376*g/cm3);
  new G4Material("HeliumGas100mbar",z=2.,a=4.002602*g/mole, density= 0.00001762640*g/cm3);
  new G4Material("HeliumGasSat4K",z=2.,  a=4.002602*g/mole, density= 0.016891*g/cm3); // saturated vapour above liquid at 4.2K (JSL)
  new G4Material("HeliumGas5mbar4K",z=2.,a=4.002602*g/mole, density= 0.016891*5.0/1013.0*g/cm3); // typical cold exchange gas, 4.2K and 5 mbar
  new G4Material("HeliumGas2mbar4K",z=2.,a=4.002602*g/mole, density= 0.016891*2.0/1013.0*g/cm3); // typical cold exchange gas, 4.2K and 5 mbar

  if (musrParameters::boolG4OpticalPhotons) {

    FILE *fSteeringFile=fopen(parameterFileName.c_str(),"r");
    if (fSteeringFile) {
      char  line[5001];
      while (!feof(fSteeringFile)) {
	fgets(line,5000,fSteeringFile);
	if ((line[0]!='#')&&(line[0]!='\n')&&(line[0]!='\r')) {
	  char tmpString0[100]="Unset";
	  sscanf(&line[0],"%s",tmpString0);
	  if ( (strcmp(tmpString0,"/musr/ignore")!=0) &&(strcmp(tmpString0,"/musr/command")!=0) ) continue;
	  
	  
	  char tmpString1[100]="Unset",tmpString2[100]="Unset";
	  sscanf(&line[0],"%*s %s %s",tmpString1,tmpString2);
	  if (strcmp(tmpString1,"materialPropertiesTable")==0){
	    std::string materialPropertiesTableName=tmpString2;
	    G4MaterialPropertiesTable* MPT_tmp;
	    itMPT = materialPropertiesTableMap.find(materialPropertiesTableName);
	    if (itMPT==materialPropertiesTableMap.end()) {  // G4MaterialPropertiesTable of this name does not exist yet --> create it  
	      MPT_tmp = new G4MaterialPropertiesTable();
	      materialPropertiesTableMap.insert ( std::pair<std::string,G4MaterialPropertiesTable*>(materialPropertiesTableName,MPT_tmp) );
	    }
	    else {
	      MPT_tmp = itMPT->second;
	    }
	    
	    char propertyName[100];
	    int nEntries;
	    sscanf(&line[0],"%*s %*s %*s %s %d",propertyName,&nEntries);
	    //	    G4cout<<" Optical Material Def:  MPT_tmp="<<MPT_tmp<<",  materialPropertiesTableName="<<materialPropertiesTableName
	    //		     <<",  propertyName="<<propertyName<<",  nEntries="<<nEntries<<G4endl;
	    
	    if (nEntries==0) {  // AddConstProperty
	      double value;
	      sscanf(&line[0],"%*s %*s %*s %*s %*d %lf",&value);
	      MPT_tmp->AddConstProperty(propertyName,value);
	      if ( (strcmp(propertyName,"FASTSCINTILLATIONRISETIME")==0) || (strcmp(propertyName,"SLOWSCINTILLATIONRISETIME")==0) ) {
		if (value!=0) {
		  musrParameters::finiteRiseTimeInScintillator = true;
		}
	      }
	    }
	    else {              // AddProperty
	      char* pch = strstr(line,propertyName)+strlen(propertyName);
	      double value;
	      G4double photonEnergyArray[100];
	      G4double valueArray[100];
	      char dummy[100];
	      sscanf(pch,"%s",dummy); char* pch2=strstr(pch,dummy)+strlen(dummy); pch = pch2;
	      for (int i=0; i<nEntries; i++) {
		sscanf(pch,"%lf",&value);
		photonEnergyArray[i]=value;
		sscanf(pch,"%s",dummy); char* pch2=strstr(pch,dummy)+strlen(dummy); pch = pch2;
	      }
	      for (int i=0; i<nEntries; i++) {
		sscanf(pch,"%lf",&value);
		valueArray[i]=value;
		sscanf(pch,"%s",dummy); char* pch2=strstr(pch,dummy)+strlen(dummy); pch = pch2;
	      }
	      MPT_tmp->AddProperty(propertyName,photonEnergyArray,valueArray,nEntries);
	    }
	  }
	  else if (strcmp(tmpString1,"setMaterialPropertiesTable")==0){
	    char tmpString3[100]="Unset";
	    sscanf(&line[0],"%*s %*s %*s %s",tmpString3);
	    std::string materialPropertiesTableName=tmpString2;
	    std::string materialName = tmpString3;
	    G4NistManager* man = G4NistManager::Instance();
	    G4Material* myMaterial = man->FindOrBuildMaterial(materialName);  

	    G4MaterialPropertiesTable* MPT_tmp=NULL;
	    itMPT = materialPropertiesTableMap.find(materialPropertiesTableName);
	    if (itMPT==materialPropertiesTableMap.end()) {  // G4MaterialPropertiesTable of this name does not exist --> problem  
	      G4cout<<"\n\n musrDetectorConstruction::DefineMaterials(): Material Properties Table \""<<materialPropertiesTableName
		    <<"\" should be assigned to material \""<<materialName<<"\""<<G4endl;
	      G4cout<<" but the table was not defined yet (by command /musr/command materialPropertiesTable )"<<G4endl;
	      G4cout <<"  ===>  S T O P    F O R C E D"<<G4endl;
	      G4cout<<line<<G4endl;
	      exit(1);
	    }
	    else {
	      MPT_tmp = itMPT->second;
	    }
	    myMaterial->SetMaterialPropertiesTable(MPT_tmp);
	    //	    G4cout<<myMaterial<<G4endl;
	    //	    myMaterial->GetMaterialPropertiesTable()->DumpTable();
	  }
	}
      }
    }
    fclose(fSteeringFile);

    //    G4cout<<" 1eV = "<<eV<<G4endl;
    //    G4cout<<" 1MeV = "<<MeV<<G4endl;
    //    G4cout<<" 1ns = "<<ns<<G4endl;
    //
    //    G4NistManager* man = G4NistManager::Instance();
    //    G4Material* scintik = man->FindOrBuildMaterial("G4_PLASTIC_SC_VINYLTOLUENE");   
    //    G4cout<<"scintik="<<scintik<<G4endl;
    //    if (scintik!=NULL) {
    //      const G4int nEntries = 14;
    //      G4double PhotonEnergy[nEntries] = 
    //	{ 2.695*eV,   2.75489*eV, 2.8175*eV,  2.88302*eV,                 // 460, 450, 440, 430 nm
    //	  2.95167*eV, 3.02366*eV, 3.09925*eV, 3.17872*eV, 3.26237*eV,     // 420, 410, 400, 390, 380 nm
    //	  3.30587*eV, 3.35054*eV, 3.44361*eV, 3.542*eV,   3.64618*eV };   // 375, 370, 360, 350, 340 nm
    //      G4double RefractiveIndex[nEntries] = 
    //	{ 1.58, 1.58, 1.58, 1.58, 
    //	  1.58, 1.58, 1.58, 1.58, 1.58,
    //	  1.58, 1.58, 1.58, 1.58, 1.58  };
    //      G4double Absorption[nEntries] =
    //      	{ 8*cm, 8*cm, 8*cm, 8*cm, 
    //      	  8*cm, 8*cm, 8*cm, 8*cm, 8*cm,
    //      	  8*cm, 8*cm, 8*cm, 8*cm, 8*cm  };
    //      G4double ScintilFast[nEntries] =
    //	{ 0.01,  0.07, 0.15, 0.26,
    //	  0.375, 0.52, 0.65, 0.80, 0.95,
    //          1,     0.88, 0.44, 0.08, 0.01 };
    //      G4double ScintilSlow[nEntries] =
    //	{ 0.01,  0.07, 0.15, 0.26,
    //	  0.375, 0.52, 0.65, 0.80, 0.95,
    //          1,     0.88, 0.44, 0.08, 0.01 };
    //      G4MaterialPropertiesTable* myMPT1 = new G4MaterialPropertiesTable();
    //      myMPT1->AddProperty("RINDEX",        PhotonEnergy, RefractiveIndex, nEntries);
    //      myMPT1->AddProperty("ABSLENGTH",     PhotonEnergy, Absorption,      nEntries);
    //      myMPT1->AddProperty("FASTCOMPONENT", PhotonEnergy, ScintilFast,     nEntries);
    //      myMPT1->AddProperty("SLOWCOMPONENT", PhotonEnergy, ScintilSlow,     nEntries);
    //      myMPT1->AddConstProperty("SCINTILLATIONYIELD", 8400./MeV);
    //      myMPT1->AddConstProperty("RESOLUTIONSCALE",1.0);
    //      myMPT1->AddConstProperty("FASTTIMECONSTANT",1.6*ns);
    //      myMPT1->AddConstProperty("SLOWTIMECONSTANT",1.6*ns);
    //      myMPT1->AddConstProperty("YIELDRATIO",1.0);
    //      scintik->SetMaterialPropertiesTable(myMPT1);

    //      scintik->GetMaterialPropertiesTable()->DumpTable();
    //    }
  }
}


//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......


#include "G4RunManager.hh"

void musrDetectorConstruction::UpdateGeometry()
{
  G4RunManager::GetRunManager()->DefineWorldVolume(Construct());
}


void musrDetectorConstruction::ReportGeometryProblem(char myString[501]) {
  G4cout<<"\nE R R O R  in musrDetectorConstruction.cc:    "
	<<"Unknown keyword requested in \""<< parameterFileName <<"\" :"<<G4endl;
  G4cout<<"\""<<myString<<"\""<<G4endl;
  G4cout<<"S T O P     F O R C E D!"<<G4endl;
  exit(1);
}

void musrDetectorConstruction::ReportProblemInStearingFile(char* myString) {
  G4cout<<"\nE R R O R  in musrDetectorConstruction.cc:    "
	<<"Problem to interpret/execute the following line in \""<< parameterFileName <<"\" :"<<G4endl;
  G4cout<<"\""<<myString<<"\""<<G4endl;
}


G4Material* musrDetectorConstruction::CharToMaterial(char myString[100]) {
  G4Material* Material=NULL;
  G4String materialName=myString;
  G4NistManager* man = G4NistManager::Instance();
  Material = man->FindOrBuildMaterial(materialName);   
  if (Material==NULL) {
    G4cout<<"\nE R R O R  in musrDetectorConstruction.cc::CharToMaterial    "
	<<"Unknown material requested:"<<G4endl;
    G4cout<<myString<<G4endl;
    G4cout<<"S T O P     F O R C E D!"<<G4endl;
    exit(1);
  }
  return Material;
}


G4LogicalVolume* musrDetectorConstruction::FindLogicalVolume(G4String LogicalVolumeName) {
  G4LogicalVolumeStore* pLogStore = G4LogicalVolumeStore::GetInstance();
  if (pLogStore==NULL) {
    G4cout<<"ERROR:  musrDetectorConstruction.cc:    G4LogicalVolumeStore::GetInstance()  not found!"<<G4endl;
  }
  else {
   //	  for (G4int i=0; i<pLogStore->entries(); i++) {
    for (unsigned int i=0; i<pLogStore->size(); i++) {
      G4LogicalVolume* pLogVol=pLogStore->at(i);
      G4String iLogName=pLogVol->GetName(); 
      if (iLogName==LogicalVolumeName) {
	return pLogVol;
      }
    }
  }
  return NULL;
}

G4VPhysicalVolume* musrDetectorConstruction::FindPhysicalVolume(G4String PhysicalVolumeName) {
  G4PhysicalVolumeStore* pPhysStore = G4PhysicalVolumeStore::GetInstance();
  if (pPhysStore==NULL) {
    G4cout<<"ERROR:  musrDetectorConstruction.cc:    G4PhysicalVolumeStore::GetInstance()  not found!"<<G4endl;
  }
  else {
    for (unsigned int i=0; i<pPhysStore->size(); i++) {
      G4VPhysicalVolume* pPhysVol=pPhysStore->at(i);
      G4String iPhysName=pPhysVol->GetName(); 
      if (iPhysName==PhysicalVolumeName) {
	return pPhysVol;
      }
    }
  }
  G4cout<<"\n musrDetectorConstruction.cc::FindPhysicalVolume: \n          ERROR !!! Physical volume "
	   <<PhysicalVolumeName<<" not found !!!"<<G4endl;
  return NULL;
}

void musrDetectorConstruction::SetColourOfLogicalVolume(G4LogicalVolume* pLogVol,char* colour) {
  if (pLogVol!=NULL) {
    if      (strcmp(colour,"red"    )==0) {pLogVol->SetVisAttributes(G4Colour(1,0,0));}
    else if (strcmp(colour,"green"  )==0) {pLogVol->SetVisAttributes(G4Colour(0,1,0));}
    else if (strcmp(colour,"blue"   )==0) {pLogVol->SetVisAttributes(G4Colour(0,0,1));}
    else if (strcmp(colour,"lightblue")==0) {pLogVol->SetVisAttributes(G4Colour(0,1,1));}
    else if (strcmp(colour,"white"  )==0) {pLogVol->SetVisAttributes(G4Colour(1,1,1));}
    else if (strcmp(colour,"yellow" )==0) {pLogVol->SetVisAttributes(G4Colour(1,1,0));}
    else if (strcmp(colour,"black"  )==0) {pLogVol->SetVisAttributes(G4Colour(0,0,0));}
    else if (strcmp(colour,"gray"   )==0) {pLogVol->SetVisAttributes(G4Colour(0.5,0.5,0.5));}
    else if (strcmp(colour,"cyan"   )==0) {pLogVol->SetVisAttributes(G4Colour(0,1,1));}
    else if (strcmp(colour,"magenta")==0) {pLogVol->SetVisAttributes(G4Colour(1,0,1));}
    else if (strcmp(colour,"invisible" )==0) {pLogVol->SetVisAttributes(G4VisAttributes::Invisible);}

    else if (strcmp(colour,"blue_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.80,0.83,1));}
    //    else if (strcmp(colour,"lightblue")==0) {pLogVol->SetVisAttributes(G4Colour(0,0.5,1));}
    else if (strcmp(colour,"darkblue")==0) {pLogVol->SetVisAttributes(G4Colour(0,0.25,0.5));}
    else if (strcmp(colour,"fblue_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.85,.88,0.92));}
    else if (strcmp(colour,"oxsteel")==0) {pLogVol->SetVisAttributes(G4Colour(0.9,0.8,0.75));}
    else if (strcmp(colour,"darkred")==0) {pLogVol->SetVisAttributes(G4Colour(0.5,0,0));}
    else if (strcmp(colour,"MCP_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.5,0.2,.7));}
    else if (strcmp(colour,"MACOR_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.9,0.9,.1));}
    else if (strcmp(colour,"SCINT_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.5,0.5,.75));}
    else if (strcmp(colour,"dSCINT_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.3,0.3,0.3));}
    else if (strcmp(colour,"VTBB_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.9,0.9,.9));}
    else if (strcmp(colour,"Grid_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.87,0.72,0.53));} //burlywood
    else if (strcmp(colour,"RA_style")==0) {pLogVol->SetVisAttributes(G4Colour(0.8549,0.6471,0.1255));} //goldenrod

    else {
      G4cout<<"ERROR: musrDetectorConstruction::SetColourOfLogicalVolume:   unknown colour requested: "<<colour<<G4endl;
      G4cout<<"    Ignoring and continuing"<<G4endl;
    }
  }
}

