//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//*        
//             LOW ENERGY MUON SPIN RELAXATION, ROTATION, RADIATION 
//
//  ID    : LEMuSRDetectorConstruction.cc , v 1.0
//  AUTHOR: Taofiq PARAISO 
//  DATE  : 2004-06-24 16:33
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//   
//
//  &           &&&&&&&&&&                            &&&&&&&         &&&&&&&&
//  &           &                                   &&      &&       &       &&
//  &           &                   &      &       &                &       &&
//  &           &&&&&&&            &      &         &&&&&&         &&&&&&&&  
//  &           &                 &      &&                &      &      &&
//  &           &                &&     &  &     &&      &&      &        &
//  &&&&&&&&&&  &&&&&&&&&&      &  &&&&&    &&    &&&&&&&       &        &&   
//                             &
//                            &
//                           &
//                         &  
//                               DETECTOR CONSTRUCTION
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//

     
// G4 GEOMETRIC FORMS CLASSES  

#include "G4Tubs.hh"
#include "G4Box.hh"
#include "G4Trap.hh"
#include "G4Cons.hh"
#include "G4Sphere.hh"
#include "G4SubtractionSolid.hh"
#include "G4UnionSolid.hh"
#include "G4UnitsTable.hh"

// G4 VOLUME DEFINITION CLASSES
#include "G4LogicalVolume.hh"
#include "G4VPhysicalVolume.hh"
#include "G4PVReplica.hh"
#include "G4PVPlacement.hh"
#include "G4GeometryManager.hh"
#include "G4FieldManager.hh"
#include "G4PropagatorInField.hh"
#include "G4ChordFinder.hh"
#include "G4El_UsualEqRhs.hh"
#include "G4ClassicalRK4.hh"
#include "G4SimpleHeum.hh"
#include "G4SimpleRunge.hh"
#include "G4MagIntegratorStepper.hh"
#include "G4TransportationManager.hh"
#include "G4GeometryManager.hh"
#include "G4UnitsTable.hh"
//#include "G4RotationMatrix.hh"

// G4 CLASSES
#include "G4ios.hh"
#include <iomanip.h>


// HEADER
#include "LEMuSRDetectorConstruction.hh"
#include "LEMuSRDetectorMessenger.hh"

 
// process remove
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleChange.hh"
#include "G4ProcessVector.hh"
#include "G4ProcessManager.hh"
#include "G4VProcess.hh"

// electric fieldmap
#include "LEMuSRElectricField.hh"
#include "LEMuSRElFieldMix.hh"
#include "LEMuSRElMagField.hh"
#include "G4ElectricField.hh"
#include "G4ElectroMagneticField.hh"
#include "G4EqMagElectricField.hh"
#include "G4El_MagEqRhs.hh"
#include "LEMuSRCryoField.hh"
#include "LEMuSRMag_SpinEqRhs.hh"
#include "LEMuSRElMag_SpinEqRhs.hh"
#include "LEMuSRMagneticField.hh"
#include "G4Mag_SpinEqRhs.hh"
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//

 
 
// CONSTRUCTOR & DESTRUCTOR
LEMuSRDetectorConstruction::LEMuSRDetectorConstruction()
{
  MaterialsDefinition ();
  Messenger = new LEMuSRDetectorMessenger(this);
  
  //default visualization
  dSPhi = 0*deg;    // starting angle
  dEPhi = 360*deg;  // ending angle

  FieldMapsDir=getenv("LEMuSR_FIELDMAPS_DIR");
  if(FieldMapsDir)
    
    G4cout<<"Fied Maps Directory is: "<< FieldMapsDir<<endl;
  else 
    G4cout<<"Fied Maps Directory is not defined!!!"<<endl;

 
#ifdef LEMU_GET_NEWMAPS  
 NEWMAPS();
#endif 

  //do not change following values!!!________________________________
  AsymCheck=0; // test asymmetry
  scint = 0; // initial state for the scintillator sensitive detector
  mcp = 0; // initial state for the mcp sensitive detector
  cryo = 0; // initial state for the cryo sensitive detector
  mcdetector = 1;// default apparatus with mcp detector
  L3FieldVal=6.78; // initial state for the third lönse field
  FieldStepLim=10.*mm;
  Grid=1;
  Guards=0;
  Material_SAH="copper";
  //_________________________________________________________________

  // can be changed
  magfield   = 1;// magfield enabled
  elfield    = 0;// 3rd lens elfield / 0 = disabled
  anode_elfield =0; //anode field /  0 = disabled
  trigger_field = 1;// trigger field / 1 = enabled
  AnodeFieldVal=1;// scale of RA field
  RALval=0.; // left anode voltage
  RARval=0.; // right anode voltage
  cfthk = 1.75;// carbon foil thickness in unit mug/cm2
  cryoFieldLength = 3.5; // cryo field length
  cryoVoltage = 12.;  // cryo voltage
  B=50.;         // magfield value

  theDetector= this;
}

LEMuSRDetectorConstruction::~LEMuSRDetectorConstruction()
{
 
}

LEMuSRDetectorConstruction*  LEMuSRDetectorConstruction::theDetector=0;
LEMuSRDetectorConstruction*  LEMuSRDetectorConstruction::GetInstance()
{
  return theDetector;
}



// CONTRUCT THE DETECTOR


G4VPhysicalVolume* LEMuSRDetectorConstruction::Construct()
{
  return  lemuDetector();
}



//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
//                            DEFINE THE DETECTOR
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
	
G4VPhysicalVolume* LEMuSRDetectorConstruction::lemuDetector() // !mind the V in G4VP...
{

  //! Definition of the top mothe volume: the laboratory. Refered to as Wolrd.
  // +++++++++++++++++++++++++++++++DEFINE THE MOTHER VOLUME:  THE LABORATOY++++++++++++++++++++++
  // solid
  G4double LABO_x = 1*m;
  G4double LABO_y = 1*m;
  G4double LABO_z = 2*m;

  LABO_box = new G4Box("World_box",LABO_x,LABO_y,LABO_z);
  // logical volume
  LABO_material = G4Material::GetMaterial("Air");
  lv_LABO  = new G4LogicalVolume(LABO_box,LABO_material,"lv_World",0,0,0);

  // physical volume
  pv_LABO  = new G4PVPlacement(0,                   // no rotation matrix
			       G4ThreeVector(),     // ()==(0,0,0)
			       lv_LABO,             // logical volume
			       "pv_World",          // name
			       0,                   // no mother volume
			       false,               // always false 
			       0);                  // !!! lv_LABO is the world logical, mother volume is 0 for the world!

  //SET VISUAL ATTRIBUTES  
  //-------NONE----------
 
  lv_LABO->SetVisAttributes(G4VisAttributes::Invisible);	
  G4UserLimits* LABO_lim = new G4UserLimits();   
  LABO_lim->SetUserMinEkine(1.*eV);
  // LABO_lim->SetUserMaxTrackLength(1.2*m);

  lv_LABO->SetUserLimits(LABO_lim);
  
  //---------------------


  //                    END OF LABORATORY DEFINITION                     //
  


  // &&&&&&&&&&&&&&&&  ADD THE OTHER DETECTOR VOLUMES  &&&&&&&&&&&&&&&&&&&&&//
  //! Definition of the other volumes:

  //! * -# Definition the attributes.
  // LOAD ATTRIBUTES AND USER LIMIT
  LoadAttributes();
  //-------------------------------
  
  // main materials
  //! * -# Definition of the materials
  Vacuum        = G4Material::GetMaterial("vacuum");
  SSteel        = G4Material::GetMaterial("stainless_steel");
  //-------------------------------
  
  //! *-# Add the MCP and Gate Valve chamber.
  lemuMCP2();

//! If <tt>asymcheck==1</tt> then build a spherical detector around mcp chamber to test the asymmetry. Shall be modified in the future.
  if(AsymCheck==1)
    { 
      lemuAsym();
    }


//! If <tt>asymcheck==0</tt> then build the trigger detector, the gate valve chamber, the third lens, the anode and the scintillators.
  if(AsymCheck==0)
    {  
      
      lemuTrigger_Detector();
      lemuCGate();
      lemuLinse3();
      lemuANODE();
      lemuSCINT();

#ifdef LEMU_TEST_FOCAL_LENGTH
 //! If <tt>LEMU_TEST_FOCAL_LENGTH</tt> is defined then 
     lemuFieldCheck();
#endif

      //! Sensitive Detection
      /*!
       * The sensitive detector and the hit collection it builds must be singletons, i.e. they can be instanciated only once. Hence, the variable <tt>cryo, mcp</tt> and <tt>scint</tt> are set to 1 as soon as the sensitive detector is built.
       */
    
      if(mcdetector==0)    //! If <tt>mcdetector==0</tt> then use cryostat
	{
	  lemuCRYO();      
	  if(cryo==0)
	    {
	      G4SDManager* SDMGR = G4SDManager::GetSDMpointer();
	      
	      G4String CryoName = "/LEMuSR/Cryo_sample";
	      
	      CryoSD = new LEMuSRCryoSD(CryoName);
	      
	      SDMGR->AddNewDetector(CryoSD);
	      cryo=1;
	    }
	  
	  lv_SAH2->SetSensitiveDetector(CryoSD);
	  
	}

      
      else if(mcdetector==1)                 //! If <tt>mcdetector==1</tt>then use micro channel detector
	{
	  lemuMCPdet();
	  if(mcp==0)
	    {
	      G4SDManager* SDMGR = G4SDManager::GetSDMpointer();
	      
	      G4String McpName = "/LEMuSR/MCP";
	      
	      McpSD = new LEMuSRMcpSD(McpName);
	      
	      SDMGR->AddNewDetector(McpSD);
	      mcp=1;
	    }
	  
	  lv_DMCP->SetSensitiveDetector(McpSD);
	  
	}
      
      
      //SENSITIVE DETECTOR
      
      
      if(scint==0)
	{ 
	  G4SDManager* SDMGR = G4SDManager::GetSDMpointer();
	  
	  G4String iScintName = "/LEMuSR/Scintillator/Inner";
	  G4String oScintName = "/LEMuSR/Scintillator/Outer";
	
	  iScintSD = new LEMuSRScintSD(iScintName);
	  oScintSD = new LEMuSROScintSD(oScintName);
	
	  SDMGR->AddNewDetector(iScintSD);
	  SDMGR->AddNewDetector(oScintSD);
	  scint=1;
	}      
      
      lv_SCIS->SetSensitiveDetector(iScintSD);
      lv_SCOS->SetSensitiveDetector(oScintSD);
      
    }    
  
  
  



  // PRINT STATUS  
  G4cout<<"geometry defined"<<G4endl;
  
  PrintStatus();

  return pv_LABO;
  
}








//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$// 
//                               DEFINE THE MCP2
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//


void LEMuSRDetectorConstruction::lemuMCP2()
{
  
  // Basic tube
  
  // solid
  
  // main volumes  
  MCPV_tube= new G4Tubs( "sMCPV", 0.00*cm, 7.65*cm, 25.45*cm, dSPhi, dEPhi);
  G4cout<<dSPhi<<"   "<<dEPhi<<G4endl;
  MCPS_tube= new G4Tubs( "sMCPS", 7.65*cm, 7.95*cm, 16.2*cm, dSPhi, dEPhi);
  F160_tube= new G4Tubs( "sF160", 7.95*cm, 10.125*cm,1.1*cm, dSPhi, dEPhi);
  F100_tube= new G4Tubs( "sF100", 0.00*cm, 7.65*cm, .5*cm, dSPhi, dEPhi);
  F200_tube= new G4Tubs( "sF200", 7.65*cm, 10.325*cm,1.2*cm, dSPhi, dEPhi);
  

  // gate valve chamber  
  GATV_tube= new G4Tubs( "sGATV",7.65*cm, 10.325*cm, 9.25*cm, dSPhi, dEPhi);
  GATS_tube= new G4Tubs( "sGATS", 10.325*cm, 12.65*cm, 9.25*cm, dSPhi, dEPhi);

  G4Transform3D tr_gatv;
  tr_gatv=G4Translate3D(0.,0.,(-25.45+9.25)*cm);

  //  MCPV_vtube= new G4UnionSolid("vMCPV", MCPV_tube, GATV_tube,tr_gatv); 

  // logical volumes : solid + material
  
    
  
  lv_MCPS  = new G4LogicalVolume( MCPS_tube  , SSteel     ,"lv_MCPS",0,0,0); 
  lv_F160  = new G4LogicalVolume( F160_tube  , SSteel     ,"lv_F160",0,0,0); 
  lv_F100  = new G4LogicalVolume( F100_tube  , SSteel     ,"lv_F100",0,0,0); 
  lv_F200  = new G4LogicalVolume( F200_tube  , SSteel     ,"lv_F200",0,0,0); 


  lv_GATV  = new G4LogicalVolume( GATV_tube  , Vacuum     ,"lv_GATV",0,0,0);  
  
  lv_GATS  = new G4LogicalVolume( GATS_tube  , SSteel     ,"lv_GATS",0,0,0);  
  
  // try to make boolean sum of gatv_mcpv

  // logical and physical volume
 
  //----------------------------------------------------//
  // BUILD THE FIELD OF THE ANODE AND RETURN LV_MCPV
  buildAnodeField();// defines lv_MCPV's field manager GFieldMgr
  //----------------------------------------------------//
 
  // set MCPV z position !!!
  mcpv_z=-9.25*cm;




  if(AsymCheck!=1){
    pv_MCPS = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 0*cm),lv_MCPS ,"pv_MCPS",lv_LABO, false, 0 );
    pv_F160 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, -15.10*cm),lv_F160 ,"pv_F160",lv_LABO, false, 0 );
    pv_F100 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, +16.2*cm),lv_F100 ,"pv_F100",lv_LABO, false, 0 );

    G4VPhysicalVolume* pv_F101;
    pv_F101 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, -124.*cm),lv_F100 ,"pv_F101",lv_LABO, false, 0 );
    
    GATVz= -25.45;
    pv_F200 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 8.05*cm),lv_F200 ,"pv_F200",lv_GATV, false, 0 );
    pv_GATS = new G4PVPlacement( 0, G4ThreeVector(0 *cm, 0*cm,GATVz*cm),lv_GATS ,"pv_GATS",lv_LABO, false, 0 );
    pv_GATV = new G4PVPlacement( 0, G4ThreeVector(0 *cm, 0*cm,GATVz*cm),lv_GATV ,"pv_GATV",lv_LABO, false, 0 );
  }
 


  pv_MCPV = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, mcpv_z),lv_MCPV ,"pv_MCPV",lv_LABO, false, 0 );
 
 




  // Apply attributes and user limit
 
  lv_MCPV->SetVisAttributes(G4VisAttributes::Invisible);
  lv_MCPS->SetVisAttributes(Blue_style);	
  lv_F160->SetVisAttributes(fBlue_style);	
  lv_F100->SetVisAttributes(fBlue_style);	
  lv_F200->SetVisAttributes(fBlue_style);	
  lv_GATV->SetVisAttributes(G4VisAttributes::Invisible);	
  lv_GATS->SetVisAttributes(Blue_style);	

  	
  // user limits
  G4UserLimits* RAV_lim = new G4UserLimits();   
  RAV_lim -> SetMaxAllowedStep(FieldStepLim );
  //RAV_lim->SetUserMaxTrackLength(1.2*m);
  RAV_lim-> SetUserMinEkine(1.*eV);
  lv_MCPV->SetUserLimits(RAV_lim);	
  // 
  
}


//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
//                               DEFINE THE ANODE
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//

void LEMuSRDetectorConstruction::lemuANODE()
{
  // conical anode

  G4double dSPhie=-acos(1/4.51469);
  G4double dEPhie=2*acos(1/4.51469);
  RA_E_cone= new G4Cons( "sRA_E", 4.51469*cm,6.25*cm,3.35*cm,3.9*cm,2.25*cm, dSPhie, dEPhie);

  RA_M_cone= new G4Cons( "sRA_M", 5.67937*cm,6.25*cm,4.51469*cm,6.25*cm,2.25*cm, dSPhie, dEPhie);

  RA_Ebox = new G4Box("RA_Ebox", 1.*cm,12.5*cm,2.25*cm );
  RA_Mbox = new G4Box("RA_Mbox", 1.*cm,12.5*cm,2.25*cm );

  RA_G_tube= new G4Tubs( "sRA_G", 5.8*cm,6.25*cm,5.55*cm, dSPhi, dEPhi);
 

  // logical volumes
  lv_RA_E  = new G4LogicalVolume( RA_E_cone   , SSteel     ,"lv_RA_E",0,0,0);  
  lv_RA_M  = new G4LogicalVolume( RA_M_cone   , SSteel     ,"lv_RA_M",0,0,0); 
  lv_RA_G  = new G4LogicalVolume( RA_G_tube  , SSteel     ,"lv_RA_G",0,0,0);  
 

  // physical volumes
  RA_Gz= -25.45+3.75;
  RA_Ez= -10.35+2.25; 
  RA_Mz= -10.35-2.25;


  // Mother Volume is lv_MCPV!!!!
  pv_RA_E = new G4PVPlacement( 0, G4ThreeVector( 0*cm, 0*cm,    RA_Ez*cm-mcpv_z),lv_RA_E ,"pv_RA_E",lv_MCPV, false, 0 );
  pv_RA_M = new G4PVPlacement( 0, G4ThreeVector( 0*cm, 0*cm,    RA_Mz*cm-mcpv_z),lv_RA_M ,"pv_RA_M",lv_MCPV, false, 0 );
  pv_RA_G = new G4PVPlacement( 0, G4ThreeVector( 0*cm, 0*cm,    RA_Gz*cm-mcpv_z),lv_RA_G ,"pv_RA_G",lv_MCPV, false, 0 );

  rotation1=G4RotateZ3D(180*deg) ;

  G4Transform3D tr_E,tr_M, trl_E, trl_M;
  trl_E=G4Translate3D(0.,0.,RA_Ez*cm-mcpv_z);
  trl_M=G4Translate3D(0.,0.,RA_Mz*cm-mcpv_z);

  tr_E=trl_E*rotation1;
  tr_M=trl_M*rotation1;


  G4VPhysicalVolume* pv_RA_E2;  
  pv_RA_E2 = new G4PVPlacement(tr_E,lv_RA_E ,"pv_RA_E2",lv_MCPV, false, 0 );
  G4VPhysicalVolume* pv_RA_M2;
  pv_RA_M2 = new G4PVPlacement(tr_M,lv_RA_M ,"pv_RA_M2",lv_MCPV, false, 0 ); 


  // Visual attributes
  lv_RA_E->SetVisAttributes(lBlue_style);	
  lv_RA_M->SetVisAttributes(dBlue_style);	
  lv_RA_G->SetVisAttributes(lBlue_style);
  

}







//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
//                               DEFINE THE CRYOSTAT
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//

void LEMuSRDetectorConstruction:: lemuCRYO()
{

  // cu or al plates
  SAH1_tube= new G4Tubs( "sSAH1", 0.*cm,3.5*cm,0.25*cm, dSPhi, dEPhi);
  SAH2_tube= new G4Tubs( "sSAH2", 0.*cm,3.5*cm,0.2*cm, dSPhi, dEPhi);
  SAH3_tube= new G4Tubs( "sSAH3", 2.*cm,3.5*cm,0.05*cm, dSPhi, dEPhi);
  SAPH_tube= new G4Tubs( "sSAPH", 0.*cm,3.0*cm,0.3*cm, dSPhi, dEPhi);

  // cryo
  COFI_tube= new G4Tubs( "sCOFI", 0.*cm,2.75*cm,0.5*cm, dSPhi, dEPhi);
  CRY1_tube= new G4Tubs( "sCRY1", 0.*cm,1.5*cm,0.35*cm, dSPhi, dEPhi);
  CRY2_tube= new G4Tubs( "sCRY2", 0.5*cm,1.5*cm,2.5*cm, dSPhi, dEPhi);
  CRY3_tube= new G4Tubs( "sCRY3", 3.8*cm,4.7*cm,0.55*cm, dSPhi, dEPhi);
  CRY4_tube= new G4Tubs( "sCRY4", 1.5*cm,3.8*cm,0.1*cm, dSPhi, dEPhi);
  CRSH_tube= new G4Tubs( "sCRSH", 4.7*cm,4.8*cm,4.5*cm, dSPhi, dEPhi);//HE shield
  CRSH2_tube= new G4Tubs( "sCRSH2", 3.0*cm,4.8*cm,.05*cm, dSPhi, dEPhi);//front HE shield

  //materials
  SAH_material  = G4Material::GetMaterial(Material_SAH);//G4Material::GetMaterial("aluminium");
  SAPH_material = G4Material::GetMaterial("saphire");
  Copper        = G4Material::GetMaterial("copper");


  Guard_Rings = new G4Tubs ("sGuard",3.0*cm,3.5*cm,0.25*cm, dSPhi, dEPhi);


  // logicals volumes
  
  
  // sample MAGNETIC field
  sampleField = new LEMuSRRNDMAGField(G4ThreeVector(0.,0.,100*gauss),1.);
    
  G4Mag_SpinEqRhs *Mag_SpinEqRhs;
  G4MagIntegratorStepper *pStepper;
  Mag_SpinEqRhs = new G4Mag_SpinEqRhs(sampleField);
  pStepper = new G4ClassicalRK4( Mag_SpinEqRhs,12 );
    
  G4ChordFinder* pChordFinder = new G4ChordFinder(sampleField,1.e-5* mm, pStepper );
  G4FieldManager* sampleFieldMgr = new G4FieldManager(); // 1
  sampleFieldMgr->SetDetectorField(sampleField,true);
  sampleFieldMgr->SetChordFinder(pChordFinder);
    
    
  lv_SAH1  = new G4LogicalVolume( SAH1_tube  , SAH_material  ,"lv_SAH1",0,0,0);  
  lv_SAH2  = new G4LogicalVolume( SAH2_tube  , SAH_material  ,"lv_SAH2",0,0,0); 
  lv_SAH3  = new G4LogicalVolume( SAH3_tube  , SAH_material  ,"lv_SAH3",0,0,0);  
  lv_SAPH  = new G4LogicalVolume( SAPH_tube  , SAPH_material ,"lv_SAPH",0,0,0);
  lv_COFI  = new G4LogicalVolume( COFI_tube  , Copper        ,"lv_COFI",0,0,0); 
  lv_CRY1  = new G4LogicalVolume( CRY1_tube  , Copper        ,"lv_CRY1",0,0,0); 
  lv_CRY2  = new G4LogicalVolume( CRY2_tube  , Copper        ,"lv_CRY2",0,0,0);  
  lv_CRY3  = new G4LogicalVolume( CRY3_tube  , Copper        ,"lv_CRY3",0,0,0);
  lv_CRY4  = new G4LogicalVolume( CRY4_tube  , Copper        ,"lv_CRY4",0,0,0); 
  lv_CRSH  = new G4LogicalVolume( CRSH_tube  , Copper        ,"lv_CRSH",0,0,0); 
  lv_CRSH2  = new G4LogicalVolume( CRSH2_tube  , Copper        ,"lv_CRSH2",0,0,0); 

  lv_Guards = new G4LogicalVolume(Guard_Rings, Copper, "lv_GRING",0,0,0);



  // physical volumes
  offset=0.0;
  pv_SAH1 = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 2.65*cm-mcpv_z), lv_SAH1 ,"pv_SAH1",lv_MCPV,false, 0 );
  pv_SAH2 = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 1.6*cm-mcpv_z), lv_SAH2 ,"pv_SAH2",lv_MCPV, false, 0 );
  //  pv_SAH3 = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 1.35*cm-mcpv_z),lv_SAH3 ,"pv_SAH3",lv_MCPV, false, 0 );
  pv_SAPH = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 2.10*cm-mcpv_z),lv_SAPH ,"pv_SAPH",lv_MCPV, false, 0 );
  pv_COFI = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 3.40*cm-mcpv_z),lv_COFI ,"pv_COFI",lv_MCPV, false, 0 );
  pv_CRY1 = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 4.25*cm-mcpv_z),lv_CRY1 ,"pv_CRY1",lv_MCPV, false, 0 );
  pv_CRY2 = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 6.75*cm-mcpv_z),lv_CRY2 ,"pv_CRY2",lv_MCPV, false, 0 );
  pv_CRY3 = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 5.10*cm-mcpv_z),lv_CRY3 ,"pv_CRY3",lv_MCPV, false, 0 );
  pv_CRY4 = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 5.10*cm-mcpv_z),lv_CRY4 ,"pv_CRY4",lv_MCPV, false, 0 );
  pv_CRSH = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 1.6*cm-mcpv_z),lv_CRSH ,"pv_CRSH", lv_MCPV, false, 0 );
  pv_CRSH2 = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 1.6*cm-mcpv_z-4.55*cm),lv_CRSH2 ,"pv_CRSH2", lv_MCPV, false, 0 );
  
  pv_Guard1 = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 1.6*cm- 1.43333*cm-mcpv_z), lv_Guards ,"pv_G_Ring1",lv_MCPV, false, 0);
  pv_Guard2 = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 1.6*cm- 1.43333*cm- 1.43333*cm-mcpv_z), lv_Guards ,"pv_G_Ring2",lv_MCPV, false, 0);


  // Visual Attributes
  lv_SAH1->SetVisAttributes(Red_style);	
  lv_SAH2->SetVisAttributes(Red_style);
  lv_SAH3->SetVisAttributes(Red_style);	
  lv_SAPH->SetVisAttributes(oxsteel);	
  lv_COFI->SetVisAttributes(dRed_style);	
  lv_CRY1->SetVisAttributes(dRed_style);	
  lv_CRY2->SetVisAttributes(dRed_style);	
  lv_CRY3->SetVisAttributes(dRed_style);	
  lv_CRY4->SetVisAttributes(dRed_style);	
  lv_CRSH->SetVisAttributes(dRed_style);
  lv_CRSH2->SetVisAttributes(Red_style);
  




}





//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
//                            DEFINE THE MICRO CHANNEL-DETECTOR
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//

void LEMuSRDetectorConstruction::  lemuMCPdet()
{ 
 
  //MCP
  DMCP_tube= new G4Tubs( "sDMCP",0.*cm,2.15*cm,0.15*cm , dSPhi, dEPhi);
  MCPM_tube= new G4Tubs( "sMCPM", 2.40*cm, 3.25*cm, 0.075*cm, dSPhi, dEPhi);
  MCPA_box = new G4Box( "sMCPA", 3.65*cm, 3.65*cm, 0.40*cm);
  ANVA_tube= new G4Tubs( "sANVA", 0.00*cm, 2.75*cm, 0.15*cm, dSPhi, dEPhi);
  MCSR_box = new  G4Box( "sMCSR", 3.65*cm, 3.65*cm, 0.10*cm);
  MCVR_tube= new G4Tubs( "sMCVR", 0.00*cm, 2.75*cm, 0.10*cm, dSPhi, dEPhi);
  MCSS_tube= new G4Tubs( "sMCSS", 4.00*cm, 4.80*cm, 0.25*cm, dSPhi, dEPhi);

  //materials
 
  Macor         = G4Material::GetMaterial("macor");
  DMCP_material = G4Material::GetMaterial("mcpglass");
 
  
  // logicals volumes
  lv_DMCP  = new G4LogicalVolume( DMCP_tube  , DMCP_material ,"lv_DMCP",0,0,0);
  lv_MCPM  = new G4LogicalVolume( MCPM_tube  , Macor         ,"lv_MCVR",0,0,0); 
  lv_MCPA  = new G4LogicalVolume( MCPA_box   , SSteel        ,"lv_MCPA",0,0,0); 
  lv_ANVA  = new G4LogicalVolume( ANVA_tube  , Vacuum        ,"lv_ANVA",0,0,0); 
  lv_MCSR  = new G4LogicalVolume( MCSR_box   , SSteel        ,"lv_MCSR",0,0,0);  
  lv_MCVR  = new G4LogicalVolume( MCVR_tube  , Vacuum        ,"lv_MCVR",0,0,0); 
  lv_MCSS  = new G4LogicalVolume( MCSS_tube  , SSteel        ,"lv_MCSS",0,0,0); 
 

  // physical volumes
  pv_DMCP = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 2.15*cm-mcpv_z),lv_DMCP ,"pv_DMCP",lv_MCPV, false, 0 );
  pv_MCPM = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 1.955*cm-mcpv_z),lv_MCPM ,"pv_MCPM",lv_MCPV, false, 0 );
  pv_MCPM2= new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 2.405*cm-mcpv_z),lv_MCPM ,"pv_MCPM2",lv_MCPV, false, 0 );
  pv_MCSR = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 2.63*cm-mcpv_z),lv_MCSR ,"pv_MCSR",lv_MCPV, false, 0 );
  pv_MCVR = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 0.0*cm),lv_MCVR ,"pv_MCVR",lv_MCSR, false, 0 );//CF SUBSTRACTION
  pv_MCPA = new G4PVPlacement( 0, G4ThreeVector(0 *cm,0 *cm, 3.73*cm-mcpv_z),lv_MCPA ,"pv_MCPA",lv_MCPV, false, 0 );
  pv_ANVA = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, -0.25*cm),lv_ANVA ,"pv_ANVA",lv_MCPA, false, 0 ); 
  pv_ANVA2= new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 0.25*cm),lv_ANVA ,"pv_ANVA2",lv_MCPA, false, 0 );
  pv_MCSS = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 6.38*cm-mcpv_z),lv_MCSS ,"pv_MCSS",lv_MCPV, false, 0 );
  
  // Visual Attributes
  lv_DMCP->SetVisAttributes(MCP_style);	
  lv_MCPM->SetVisAttributes(MACOR_style);
  lv_MCSR->SetVisAttributes(Green_style);
  lv_MCVR->SetVisAttributes(VTBB_style);
  lv_MCPA->SetVisAttributes(Green_style);
  lv_ANVA->SetVisAttributes(VTBB_style);
  lv_MCSS ->SetVisAttributes(Green_style);

}

 


//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
//                            DEFINE THE SCINTILLATOR
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
void LEMuSRDetectorConstruction::lemuSCINT()
{

  // solids 
  SCIS_tube= new G4Tubs("sSCIS",9.0*cm,9.5*cm, 13.0*cm, -45*deg, +90*deg);
  SCOS_tube= new G4Tubs("sSCOS",9.6*cm,10.1*cm, 13.0*cm, -45*deg, +90*deg);
  
  // materials
  SC_material=  G4Material::GetMaterial("scint");

  // logical
  lv_SCIS= new G4LogicalVolume(SCIS_tube,SC_material,"lv_SCIS",0,0,0);
  lv_SCOS= new G4LogicalVolume(SCOS_tube,SC_material,"lv_SCOS",0,0,0);
  
  // physical
  rotation1=G4RotateZ3D(90*deg) ;
  rotation2=G4RotateZ3D(180*deg) ;
  rotation3=G4RotateZ3D(270*deg) ;

  pv_SCISr = new G4PVPlacement( rotation2,lv_SCIS ,"pv_SCISr",lv_LABO, false, 0 ); 
  pv_SCOSr = new G4PVPlacement( rotation2,lv_SCOS ,"pv_SCOSr",lv_LABO, false, 0 ); 

  
  if(halfview==0)
    {
      pv_SCISt = new G4PVPlacement( rotation1,lv_SCIS ,"pv_SCISt",lv_LABO, false, 0 ); 
      pv_SCOSt = new G4PVPlacement( rotation1,lv_SCOS ,"pv_SCOSt",lv_LABO, false, 0 ); 
      
      pv_SCISl = new G4PVPlacement( 0 , G4ThreeVector(0 *cm,0 *cm, 0*cm),lv_SCIS ,"pv_SCISl",lv_LABO, false, 0 );
      pv_SCOSl = new G4PVPlacement( 0 , G4ThreeVector(0 *cm,0 *cm, 0*cm),lv_SCOS ,"pv_SCOSl",lv_LABO, false, 0 ); 
      
      pv_SCISb = new G4PVPlacement( rotation3,lv_SCIS ,"pv_SCISb",lv_LABO, false, 0 ); 
      pv_SCOSb = new G4PVPlacement( rotation3,lv_SCOS ,"pv_SCOSb",lv_LABO, false, 0 ); 

    }
  else if(halfview==1)
    {
      pv_SCISb = new G4PVPlacement( rotation3,lv_SCIS ,"pv_SCISb",lv_LABO, false, 0 ); 
      pv_SCOSb = new G4PVPlacement( rotation3,lv_SCOS ,"pv_SCOSb",lv_LABO, false, 0 ); 
      pv_SCISt = new G4PVPlacement( rotation1,lv_SCIS ,"pv_SCISt",lv_LABO, false, 0 ); 
      pv_SCOSt = new G4PVPlacement( rotation1,lv_SCOS ,"pv_SCOSt",lv_LABO, false, 0 ); 
    }
  

  // vis attributes
  lv_SCIS->SetVisAttributes(SCINT_style);
  lv_SCOS->SetVisAttributes(dSCINT_style);
}



//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
//                            DEFINE THE THIRD LENS
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//


void LEMuSRDetectorConstruction::lemuLinse3()
{

  // L3 tube
  L3VA_tube= new G4Tubs( "sL3VA", 0.*cm,10.0*cm,22.0*cm, dSPhi, dEPhi);
  L3ST_tube= new G4Tubs( "sL3ST", 10.0*cm, 10.3*cm, 22.0*cm, dSPhi, dEPhi);

  L3F_tube= new G4Tubs( "sL3F", 10.3*cm, 12.65*cm, 1.2*cm, dSPhi, dEPhi);

  // Ground Potential tubes
  L3GP1= new G4Tubs("LGP1", 6.5*cm, 6.7*cm, 6.65*cm, dSPhi, dEPhi);
  L3GP2= new G4Tubs("LGP2", 8.1*cm, 8.3*cm, 6.65*cm, dSPhi, dEPhi);
  L3GP3= new G4Tubs("LGP3", 6.7*cm,8.1*cm,0.4*cm, dSPhi, dEPhi);
 
  // High Potential tube
  
  L3HP1= new G4Tubs("LHP1", 6.5*cm, 8.3*cm, 5.5*cm, dSPhi, dEPhi);
  L3HP2= new G4Tubs("LHP2", 6.7*cm, 8.1*cm, 5.*cm, dSPhi, dEPhi);
  L3HP4= new G4Tubs("LHP4", 8.1*cm, 8.3*cm, 0.6*cm, dSPhi, dEPhi);
  L3HP5= new G4Tubs("LHP5", 6.7*cm, 6.85*cm, 0.75*cm, dSPhi, dEPhi);
  
  //  L3HP_tube= new G4SubtractionSolid("sL3HP", L3HP1, L3HP2);
  
   
  // Logical volumes

  // electric field
  
  if(elfield==1)
    {
      
      G4ElectricField* L3Field = new LEMuSRElectricField(L3FieldVal,
							FieldMapsDir+"/ThirdLens/L3b.map"
							 ,"dm",-567,60,60,100);
      
      //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      
      L3FieldMgr =  new G4FieldManager();//1
      
      G4MagIntegratorStepper *pStepper;
      G4El_UsualEqRhs  *fEquation =  new G4El_UsualEqRhs(L3Field); 

      pStepper    = new G4ClassicalRK4(   fEquation, 12 );
       
      // equation considers spin or not
      G4ChordFinder*  pChordFinder = new G4ChordFinder( L3Field,
							1.e-10 * mm,      // Minimum step size: must be very small for a precise calculation of transport energy
							pStepper);

      L3FieldMgr->SetDetectorField(L3Field);
      L3FieldMgr->SetChordFinder(pChordFinder);
      
      lv_L3VA  = new G4LogicalVolume( L3VA_tube  , Vacuum        ,"lv_L3VA",L3FieldMgr,0,0);  

    }
  
  if(elfield==0)
    {
      lv_L3VA  = new G4LogicalVolume( L3VA_tube  , Vacuum        ,"lv_L3VA",0,0,0);  
    }
  
  lv_L3ST  = new G4LogicalVolume( L3ST_tube  , SSteel        ,"lv_L3ST",0,0,0);  
  
  lv_L3F   = new G4LogicalVolume( L3F_tube  , SSteel        ,"lv_L3F",0,0,0);  
  
  lv_L3GP1=  new G4LogicalVolume( L3GP1  , SSteel        ,"lv_L3GP1",0,0,0); 
  lv_L3GP2=  new G4LogicalVolume( L3GP2  , SSteel        ,"lv_L3GP2",0,0,0); 
  lv_L3GP3=  new G4LogicalVolume( L3GP3  , SSteel        ,"lv_L3GP3",0,0,0); 
  
  lv_L3HP=  new G4LogicalVolume( L3HP1  , SSteel        ,"lv_L3HP",0,0,0); 
  lv_L3HP4= new G4LogicalVolume( L3HP4      , SSteel        ,"lv_L3HP4",0,0,0); 
  lv_L3HP5= new G4LogicalVolume( L3HP5      , SSteel        ,"lv_L3HP5",0,0,0); 


  // Physical volumes
  L3z= -56.7;

  pv_L3VA = new G4PVPlacement( 0, G4ThreeVector( 0*cm,0 *cm, L3z*cm),lv_L3VA ,"pv_L3VA",lv_LABO, false, 0 );
  pv_L3ST = new G4PVPlacement( 0, G4ThreeVector(0 *cm, 0*cm, L3z*cm),lv_L3ST ,"pv_L3ST",lv_LABO, false, 0 );

  pv_L3F1 = new G4PVPlacement( 0, G4ThreeVector(0 *cm, 0*cm, (L3z+20.8)*cm),lv_L3F ,"pv_L3F1",lv_LABO, false, 0 );
  pv_L3F2 = new G4PVPlacement( 0, G4ThreeVector(0 *cm, 0*cm, (L3z-20.8)*cm),lv_L3F ,"pv_L3F2",lv_LABO, false, 0 );

  //ground potential  
  pv_L3GP1 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm,13.35*cm),lv_L3GP1 ,"pv_L3GP1",lv_L3VA, false, 0 );
  pv_L3GP2 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 13.35*cm),lv_L3GP2 ,"pv_L3GP2",lv_L3VA, false, 0 );
  pv_L3GP3 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 19.6*cm),lv_L3GP3 ,"pv_L3GP3",lv_L3VA, false, 0 );
  pv_L3GP4 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 7.1*cm),lv_L3GP3 ,"pv_L3GP4",lv_L3VA, false, 0 );
  pv_L3GP5 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm,-13.35*cm),lv_L3GP1 ,"pv_L3GP5",lv_L3VA, false, 0 );
  pv_L3GP6 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, -13.35*cm),lv_L3GP2 ,"pv_L3GP6",lv_L3VA, false, 0 );
  pv_L3GP7 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, -19.6*cm),lv_L3GP3 ,"pv_L3GP7",lv_L3VA, false, 0 );
  pv_L3GP8 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, -7.1*cm),lv_L3GP3 ,"pv_L3GP8",lv_L3VA, false, 0 );


  pv_L3HP = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm,0*cm),lv_L3HP ,"pv_L3HP",lv_L3VA, false, 0 );
  pv_L3HP4 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 6.1*cm),lv_L3HP4 ,"pv_L3HP4",lv_L3VA, false, 0 );
  pv_L3HP5 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, 4.425*cm),lv_L3HP5 ,"pv_L3HP5",lv_L3VA, false, 0 );
  pv_L3HP7 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, -6.1*cm),lv_L3HP4,"pv_L3HP7",lv_L3VA, false, 0 );
  pv_L3HP8 = new G4PVPlacement( 0, G4ThreeVector( 0.*cm, 0.*cm, -4.425*cm),lv_L3HP5 ,"pv_L3HP8",lv_L3VA, false, 0 );





  //Visual Attributes:
  // Load attributes and userlimits

  lv_L3VA->SetVisAttributes(G4VisAttributes::Invisible);	
  lv_L3ST->SetVisAttributes(Blue_style);
  lv_L3F->SetVisAttributes(fBlue_style);
  
  lv_L3GP1->SetVisAttributes(lBlue_style);
  lv_L3GP2->SetVisAttributes(Blue_style);	
  lv_L3GP3->SetVisAttributes(dBlue_style);	
  

  lv_L3HP->SetVisAttributes(lBlue_style);
  lv_L3HP4->SetVisAttributes(Blue_style);
  lv_L3HP5->SetVisAttributes(dBlue_style);  

  G4UserLimits* L3V_lim = new G4UserLimits();   
  L3V_lim -> SetMaxAllowedStep(FieldStepLim );
  //L3V_lim->SetUserMaxTrackLength(1.2*m);
  L3V_lim-> SetUserMinEkine(1.*eV);
  lv_L3VA->SetUserLimits(L3V_lim);

}





//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
//                            DEFINE THE TRIGGER DETECTOR
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//

void LEMuSRDetectorConstruction::lemuTrigger_Detector()
{

  //--------------------- CYLINDER AND FLANGES--------------------
     
  // solids
  TriggerV_tube = new G4Tubs("sTriggerV",0.*cm,10.*cm,14.8*cm, dSPhi, dEPhi);
  Trigger_tube  = new G4Tubs("sTrigger",10.*cm,10.3*cm,14.8*cm, dSPhi, dEPhi);
  TriggerF_tube = new G4Tubs( "sTF", 10.3*cm, 12.65*cm, 1.2*cm, dSPhi, dEPhi);

  Trigger_box = new G4Box("TBox", 4.5*cm, 4.5*cm, 0.4*cm);
  Trigger_box2 = new G4Box("TBox", 4.*sqrt(2)*cm, 4.5*cm, 0.7/sqrt(2)*cm);

  G4double thk;
  thk = (cfthk*1.e-6/2.)*cm;//denominator must correspnd to graphite's density in material def.
  Trigger_box3 = new G4Box("TFoilBox", 6*cm, 6*cm,thk/2.);

  
  lv_TriggerV = new G4LogicalVolume(TriggerV_tube,Vacuum,"lv_TriggerV",0,0,0);
  lv_TriggerF = new G4LogicalVolume(TriggerF_tube,SSteel,"lv_TriggerF",0,0,0);
  lv_Trigger = new G4LogicalVolume(Trigger_tube,SSteel,"lv_Trigger",0,0,0);

  Carbon=  G4Material::GetMaterial("graphite");
  lv_CFOIL=new G4LogicalVolume(Trigger_box3,Carbon,"lv_CFOIL",0,0,0);

  
  G4double Triggerz = -109.2;//L3z - 22 - 15.7 -14.8;

  pv_TriggerV = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,Triggerz*cm),lv_TriggerV,"pv_TriggerV",lv_LABO, false, 0 );
  pv_TriggerF1 = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,(Triggerz+13.6)*cm),lv_TriggerF,"pv_TriggerF1",lv_LABO, false, 0 );
  pv_TriggerF2 = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,(Triggerz-13.6)*cm),lv_TriggerF,"pv_TriggerF2",lv_LABO, false, 0 );
  pv_Trigger = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,Triggerz*cm),lv_Trigger,"pv_Trigger",lv_LABO, false, 0 );
 

     
  //--------------------- CARBON FOIL-----------------------------
  
#ifndef NO_CFOIL
  pv_CFOIL = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,-4.5*cm),lv_CFOIL,"pv_CFOIL",lv_TriggerV, false, 0 );
#endif

  //--------------------- ELECTRIC FIELD ZONES--------------------


  // field
  
  T1Field = new G4UniformElectricField(G4ThreeVector(0.,0.,-23.75*kilovolt/meter));
  T1FieldMgr = new G4FieldManager();
  T1FieldMgr->SetDetectorField(T1Field);
  
  T2Field = new G4UniformElectricField(G4ThreeVector(0.,0.,+41.416*kilovolt/meter));
  T2FieldMgr = new G4FieldManager();
  T2FieldMgr->SetDetectorField(T2Field);
  
  T3Field = new G4UniformElectricField(G4ThreeVector(0.,0.,-493.75*kilovolt/meter));
  T3FieldMgr = new G4FieldManager();
  T3FieldMgr->SetDetectorField(T3Field);
  
  G4MagIntegratorStepper *pStepper;
  G4El_UsualEqRhs  *fEquation =  new G4El_UsualEqRhs(T1Field); 
  pStepper    = new G4ClassicalRK4(   fEquation, 12 );
  G4ChordFinder* pChordFinder = new G4ChordFinder( T1Field,1e-10 * mm,pStepper);
  T1FieldMgr->SetDetectorField(T1Field);
  T1FieldMgr->SetChordFinder(pChordFinder);
  
  G4MagIntegratorStepper *pStepper2;
  G4El_UsualEqRhs  *fEquation2 =  new G4El_UsualEqRhs(T2Field); 
  pStepper2    = new G4ClassicalRK4(   fEquation2, 12 );
  G4ChordFinder* pChordFinder2 = new G4ChordFinder( T2Field,1e-10 * mm,pStepper2);
  T2FieldMgr->SetDetectorField(T2Field);
  T2FieldMgr->SetChordFinder(pChordFinder2);
  
  G4MagIntegratorStepper *pStepper3;
  G4El_UsualEqRhs  *fEquation3 =  new G4El_UsualEqRhs(T3Field); 
  pStepper3    = new G4ClassicalRK4(   fEquation3, 12 );
  G4ChordFinder* pChordFinder3 = new G4ChordFinder( T3Field,1e-10 * mm,pStepper3);//minimum step =0 becuz the field is very big!
  //therefore, all min step were set to very small values, just in case.
  T3FieldMgr->SetDetectorField(T3Field);
  T3FieldMgr->SetChordFinder(pChordFinder3);
  
 
  // logical volumes

  
  lv_TriggerE=new G4LogicalVolume(Trigger_box,Vacuum,"lv_TriggerE",T1FieldMgr,0,0);
  lv_TriggerE2=new G4LogicalVolume(Trigger_box2,Vacuum,"lv_TriggerE2",T2FieldMgr,0,0);
  lv_TriggerE3=new G4LogicalVolume(Trigger_box,Vacuum,"lv_TriggerE3",T3FieldMgr,0,0);


  G4Transform3D Rotation2, transformation2, trl;
  trl=G4Translate3D(0.,0.,2.25*mm);
  Rotation2= G4Rotate3D(45*deg,G4ThreeVector(0.,1.,0.));
  transformation2=trl*Rotation2;
        

  if(trigger_field!=0)
    {
      pv_TriggerE = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,(-3.85)*cm),lv_TriggerE,"pv_TriggerE",lv_TriggerV, false, 0 );
      
      pv_TriggerE2 = new G4PVPlacement(transformation2,lv_TriggerE2,"pv_TriggerE2",lv_TriggerV, false, 0 );
      
      pv_TriggerE3 = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,(+4.3)*cm),lv_TriggerE3,"pv_TriggerE3",lv_TriggerV, false, 0 );
    }
  

  //visual attibutes
  lv_TriggerV->SetVisAttributes(G4VisAttributes::Invisible);	
  lv_Trigger->SetVisAttributes(Blue_style);
  lv_TriggerF->SetVisAttributes(fBlue_style);
  lv_CFOIL->SetVisAttributes(MACOR_style); 
 
  G4UserLimits* RAV_lim = new G4UserLimits();   
  //  RAV_lim -> SetMaxAllowedStep(FieldStepLim );
  // RAV_lim->SetUserMaxTrackLength(1.2*m);
  RAV_lim-> SetUserMinEkine(1.*eV);
  lv_TriggerV->SetUserLimits(RAV_lim);	
  
}



//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
//                            DEFINE THE COMPENSATION GATE
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//

void LEMuSRDetectorConstruction::lemuCGate()
{

  // solids
  CGateV_tube = new G4Tubs("sCGateV",0.*cm,10.*cm,7.85*cm, dSPhi, dEPhi);
  CGate_tube  = new G4Tubs("sCGate",10.*cm,10.3*cm,7.85*cm, dSPhi, dEPhi);
  CGateF_tube = new G4Tubs( "sCGF", 10.3*cm, 12.65*cm, 1.2*cm, dSPhi, dEPhi);


  // logical volumes
  lv_CGateV = new G4LogicalVolume(CGateV_tube,Vacuum,"lv_CGateV",0,0,0);
  lv_CGateF = new G4LogicalVolume(CGateF_tube,SSteel,"lv_CGateF",0,0,0);
  lv_CGate = new G4LogicalVolume(CGate_tube,SSteel,"lv_CGate",0,0,0);


  G4double CompGatez=-86.55 ;// L3z-22-7.85;

  pv_CGateV = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,CompGatez*cm),lv_CGateV,"pv_CGateV",lv_LABO, false, 0 );
  pv_CGateF1 = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,(CompGatez+6.65)*cm),lv_CGateF,"pv_CGateF1",lv_LABO, false, 0 );
  pv_CGateF2 = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,(CompGatez-6.65)*cm),lv_CGateF,"pv_CGateF2",lv_LABO, false, 0 );
  pv_CGate = new G4PVPlacement( 0,G4ThreeVector(0.*cm,0.*cm,CompGatez*cm),lv_CGate,"pv_CGate",lv_LABO, false, 0 );

  //visual attibutes
  lv_CGateV->SetVisAttributes(G4VisAttributes::Invisible);	
  lv_CGate->SetVisAttributes(Blue_style);
  lv_CGateF->SetVisAttributes(fBlue_style);

  G4UserLimits* RAV_lim = new G4UserLimits();   
  RAV_lim -> SetMaxAllowedStep(FieldStepLim );
  // RAV_lim->SetUserMaxTrackLength(1.2*m);
  RAV_lim-> SetUserMinEkine(1.*eV);
  lv_CGateV->SetUserLimits(RAV_lim);	

}



//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
//                            DEFINE THE FIELDS
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//



void LEMuSRDetectorConstruction::buildAnodeField()
{
  
  

  G4String dir= FieldMapsDir;

 int k=2*Grid+Guards;
   
  std::cout<<"buildAnodeField::case = "<<k<<std::endl;
 switch(k)
    {
      
    case 0:
      dir+="/MCPV-80-80-200/No_Grid_NoGuards/"; break; 
      
    case 1:
      dir+="/MCPV-80-80-200/No_Grid_Guards/"; break; 
      
    case 2:
      dir+="/MCPV-80-80-200/Grid_NoGuards/"; break; 
      
    case 3:
      dir+="/MCPV-80-80-200/Grid_Guards/"; break; 
      
    default: break; 
    }

 
  
  // IF THERE IS A FIELD IN THE ANODE
  if(anode_elfield==1)
    {
      
      // TEST OF TOTAL MCPV FIELD
      
      // electric field
      //      G4cout<<"offset"<<mcpv_z/mm<<G4endl;
      // left
      
      G4String leftfile="RAL.map";
      G4String leftmap = dir+leftfile;

      LEMuSRElectricField* GFieldLeft = new LEMuSRElectricField(1,leftmap,"mm",0.0,80,80,200);



      // right
      
      G4String rightfile="RAR.map";
      G4String rightmap = dir+rightfile;

      LEMuSRElectricField* GFieldRight = new LEMuSRElectricField(1,rightmap,"mm",0.0,80,80,200);

     
      // mix
      // GField0
      G4ElectricField* GField0 = 
	new LEMuSRElFieldMix(GFieldLeft,GFieldRight,RALval,RARval);
      
      // mcdetector=1 or 0; 0 for cryo mode   
      buildCryoField();//cryostat field
      
      // GField
      G4ElectricField* GField = 
      	new LEMuSRElFieldMix(GField0,cryoField,1,1-mcdetector);
            

#ifdef DEBUG_INTERPOLATING_FIELD
      G4double Efield[3];
      G4double position[4];
      position[0]=0*mm;
      position[1]=0*mm;
      position[2]=-100.*mm;
      position[3]=0;
      GField->GetFieldValue(position,Efield);
      do
	{

	  GField->GetFieldValue(position,Efield);
	  G4cout<<position[0]<<" "<<position[1]<<" "<<position[2]<<G4endl;
	  G4cout<<"Field E Value " << G4BestUnit(Efield[0]*meter,"Electric potential") <<"/m " <<Efield[1]/volt*meter <<" V/m "<< Efield[2]/volt*meter <<" V/m      " <<G4endl;
	  position[2]+=1.*mm;
	}while(position[2]<20);
#endif




      // 1 case of pure electric field in the mcp

      if(magfield==0)
	{
	  
	  GFieldMgr =  new G4FieldManager();//1
	  G4MagIntegratorStepper *pStepper;
	  G4El_UsualEqRhs  *fEquation =  new G4El_UsualEqRhs(GField); 
	  
	  pStepper    = new G4ClassicalRK4(fEquation,12);
	  // 8 is the number of parameters: position+momentum + TIME (parameter [7]
	  // in an array starting at [0])
	  
	  G4ChordFinder*  pChordFinder = new G4ChordFinder( GField,
							    1e-10 * mm, // Minimum step size: must be set to a very small value for a correct calculation of the enrgy
							    pStepper);
	  
	  GFieldMgr->SetDetectorField(GField,false);
	  GFieldMgr->SetChordFinder(pChordFinder);
	  
	  lv_MCPV  = new G4LogicalVolume( MCPV_tube, Vacuum ,"lv_MCPV",GFieldMgr,0,0);
	  
	  
#ifdef DEBUG_INTERPOLATING_FIELD
	  //**************************************************************************//
	  G4double Efield[3];
	  G4double position[4];
	  position[0]=0*mm;
	  position[1]=0*mm;
	  position[2]=-103*mm;
	  position[3]=0*mm;
	  GField->GetFieldValue(position,Efield);
	  do
	    {
	      G4cout<<"Position? "<<G4endl;
	      G4cin>>position[0]>>position[1]>>position[2]>>position[3];
	      GField->GetFieldValue(position,Efield);
	      G4cout<<"Field E Value " << G4BestUnit(Efield[0]*meter,"Electric potential") <<"/m " <<Efield[1]/volt*meter <<" V/m "<< Efield[2]/volt*meter <<" V/m " <<G4endl;
	  
	    }while(position[3]!=-1);
	  //*************************************************************************//
#endif
	}
      
      
      // 2 case of electro magnetic field
      
      G4UniformMagField* mcField;
      
      if(magfield==1)
	{
	  
#ifdef LEMU_TRANSVERSE_FIELD  
	mcField = new LEMuSRMagneticField(G4ThreeVector(0.,B*gauss,0.));
        G4cout<<"Transverse Field Applied: (0 G, " <<B <<"G, 0 G) \n"<<G4endl;
	//sleep(3); // wait 3 seconds
#else
	mcField = new LEMuSRMagneticField(G4ThreeVector(0.,0.,B*gauss));
        G4cout<<"Longtudinal Field Applied: (0 G, 0 G, " <<B <<"G) \n"<<G4endl;
	//sleep(3); // wait 3 seconds
#endif	  

	  
	  
	  G4MagneticField* EMField = new LEMuSRElMagField(GField,mcField,1.,1.);
	  
	  LEMuSRElMag_SpinEqRhs *ElMag_SpinEqRhs = new LEMuSRElMag_SpinEqRhs(EMField);
	  
	  G4MagIntegratorStepper *EMStepper;
	  
	  EMStepper = new G4ClassicalRK4( ElMag_SpinEqRhs,12 );
	  
	  G4ChordFinder* EMChordFinder = new G4ChordFinder(EMField,
							   1e-10 * mm, 
							   EMStepper );
	  
	  G4FieldManager* EMFieldMgr = new G4FieldManager(); // 1
	  
	  EMFieldMgr->SetDetectorField(EMField,true);
	  EMFieldMgr->SetChordFinder(EMChordFinder);
	  EMFieldMgr->SetFieldMagComponent(true);

	  
	  lv_MCPV  = new G4LogicalVolume( MCPV_tube  , Vacuum     ,"lv_MCPV",EMFieldMgr,0,0);
	  

	  //////////////////
#ifdef DEBUG_INTERPOLATING_FIELD
	  G4double EBfield[6];
	  G4double position[4];
	  position[0]=0*mm;
	  position[1]=0*mm;
	  position[2]=-300.*mm;
	  position[3]=0;
	  GField->GetFieldValue(position,EBfield);
	  do
	    {

	      EMField->GetFieldValue(position,EBfield);
	      G4cout<<position[0]<<" "<<position[1]<<" "<<position[2]<<G4endl;
	      G4cout<<"Field EM Field Value " << EBfield[0]/gauss <<"gauss " <<EBfield[1]/gauss <<"gauss "<< EBfield[2]/gauss <<"gauss \n" 
		    << EBfield[3]/volt*meter <<"V/m " <<EBfield[3]/volt*meter <<"V/m "<< EBfield[5]/volt*meter <<"V/m \n" <<G4endl;
	      position[2]+=10.*mm;
	    }while(position[2]<300);
#endif
	  /////////////////


	}
       
    }
     
  else if(anode_elfield == 0)
    {
      // 3 pure magnetic field 
      if(magfield==1)
	{
	
	  G4UniformMagField* mcField;
	
  
#ifdef LEMU_TRANSVERSE_FIELD  
	mcField = new LEMuSRMagneticField(G4ThreeVector(0.,B*gauss,0.));
        G4cout<<"Longitudinal Field Applied: (0 G, " <<B <<"G, 0 G) \n"<<G4endl;
	//sleep(3); // wait 3 seconds
#else
	mcField = new LEMuSRMagneticField(G4ThreeVector(0.,0.,B*gauss));
        G4cout<<"Transverse Field Applied: (0 G, 0 G, " <<B <<"G) \n"<<G4endl;
	//sleep(3); // wait 3 seconds
#endif	  
	

	  LEMuSRMag_SpinEqRhs *Mag_SpinEqRhs;
	  G4MagIntegratorStepper *pStepper;
	  Mag_SpinEqRhs = new LEMuSRMag_SpinEqRhs(mcField);
	  pStepper = new G4ClassicalRK4( Mag_SpinEqRhs,12 );
	 
	  // equation considers spin or not
	  G4ChordFinder* pChordFinder = new G4ChordFinder(mcField,
							  1.e-10* mm, 
							  pStepper );
	 
	  G4FieldManager* mcFieldMgr = new G4FieldManager(); // 1
	  // G4TransportationManager::GetTransportationManager()->GetFieldManager(); // 2
	  mcFieldMgr->SetDetectorField(mcField,true);
	  mcFieldMgr->SetChordFinder(pChordFinder);
	  mcFieldMgr->SetFieldMagComponent(true);
	  lv_MCPV  = new G4LogicalVolume( MCPV_tube  , Vacuum     ,"lv_MCPV",mcFieldMgr,0,0);
	}
      if(magfield==0)
	{
	  // 4 no field at all	  
	  lv_MCPV  = new G4LogicalVolume( MCPV_tube  , Vacuum     ,"lv_MCPV",0,0,0);
	}
      
      
    }
  
 
} 





void LEMuSRDetectorConstruction::buildCryoField()
{
  // sample ELECTRIC field
//   G4double d= cryoFieldLength*cm;
//   G4double V= cryoVoltage*kilovolt;
  
//   G4ThreeVector C_field(0.,0.,-V/d);

  G4String dir= FieldMapsDir;

 int k=2*Grid+Guards;
  switch(k)
    {
      
    case 0:
      dir+="/MCPV-80-80-200/No_Grid_NoGuards/"; break; 
      
    case 1:
      dir+="/MCPV-80-80-200/No_Grid_Guards/"; break; 
      
    case 2:
      dir+="/MCPV-80-80-200/Grid_NoGuards/"; break; 
      
    case 3:
      dir+="/MCPV-80-80-200/Grid_Guards/"; break; 
      
    default: break; 
    }
  

  G4String filename="SAMPLE.map";
  
  G4String fmap=dir+filename;
  
  cryoField =  new LEMuSRElectricField(cryoVoltage,fmap,"mm",0.0,80,80,200);//offset in milimeters)


#ifdef DEBUG_INTERPOLATING_FIELD

      G4double Efield[3];
      G4double position[4];
      position[0]=0*mm;
      position[1]=0*mm;
      position[2]=-100.*mm;
      position[3]=0;
      cryoField->GetFieldValue(position,Efield);
      do
	{
	  cryoField->GetFieldValue(position,Efield);
	  G4cout<<position[0]<<" "<<position[1]<<" "<<position[2]<<G4endl;
	  G4cout<<"Field E Value " << G4BestUnit(Efield[0]*meter,"Electric potential") <<"/m " <<Efield[1]/volt*meter <<" V/m "<< Efield[2]/volt*meter <<" V/m      " <<G4endl;
	  position[2]+=1.*mm;
	}while(position[2]<20);				      
#endif

}


 
      


void LEMuSRDetectorConstruction::NEWMAPS()
{
 
  // FIELD IN THE ANODE
  // left
  LEMuSRElectricField* LEFTMAP = 
    new LEMuSRElectricField(1,
			    FieldMapsDir+"/MCPV-80-80-200/Grid_NoGuards/RAL_Ex.txt",
			    FieldMapsDir+"/MCPV-80-80-200/Grid_NoGuards/RAL_Ey.txt", 
			    FieldMapsDir+"/MCPV-80-80-200/Grid_NoGuards/RAL_Ez.txt",
			    "mm",0.0,80,80,200);//offset in milimeters
  
  // right
  LEMuSRElectricField* RIGHTMAP = 
    new LEMuSRElectricField(1,
			    FieldMapsDir+"/MCPV-80-80-200/Grid_NoGuards/RAR_Ex.txt",
			    FieldMapsDir+"/MCPV-80-80-200/Grid_NoGuards/RAR_Ey.txt", 
			    FieldMapsDir+"/MCPV-80-80-200/Grid_NoGuards/RAR_Ez.txt",
			    "mm",0.0,80,80,200);//offset in milimeters 

 

  // sample ELECTRIC field
  
  LEMuSRElectricField* SAMPLEMAP = 
    new LEMuSRElectricField(1,
			    FieldMapsDir+"/MCPV-80-80-200/Grid_NoGuards/SAMPLE_Ex.txt",
			    FieldMapsDir+"/MCPV-80-80-200/Grid_NoGuards/SAMPLE_Ey.txt", 
			    FieldMapsDir+"/MCPV-80-80-200/Grid_NoGuards/SAMPLE_Ez.txt",
			    "mm",0.0,80,80,200);//offset in milimeters)



  
  delete LEFTMAP;
  delete RIGHTMAP;
  delete SAMPLEMAP;

}





void LEMuSRDetectorConstruction::PrintStatus()
{
  G4cout<<G4endl
	<<"              Detector Status     " <<G4endl;
  

  G4cout<<"magfield      " << magfield	<<G4endl
	<<"elfield       " <<elfield	<<G4endl
	<<"anode_elfield " <<anode_elfield	<<G4endl
	<<"trigger_field " <<trigger_field	<<G4endl
	<<"B             " <<B	<<G4endl
 	<<"GRID          " <<Grid	<<G4endl
    	<<"GUARDS        " <<Guards	<<G4endl
 	<<G4endl;

  if(FieldMapsDir)
    {
      G4cout<<"Fied Maps Directory is: "<< FieldMapsDir<<endl;
    } 
  else
    { 
      G4cout<<"Fied Maps Directory is not defined!!!"<<endl;//sleep(10);
    }
}
