// // ******************************************************************** // * DISCLAIMER * // * * // * The following disclaimer summarizes all the specific disclaimers * // * of contributors to this software. The specific disclaimers,which * // * govern, are listed with their locations in: * // * http://cern.ch/geant4/license * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. * // * * // * This code implementation is the intellectual property of the * // * GEANT4 collaboration. * // * By copying, distributing or modifying the Program (or any work * // * based on the Program) you indicate your acceptance of this * // * statement, and all its terms. * // ******************************************************************** // // // $Id: MuCool.cc,v 1.4 2002/01/09 17:23:48 ranjard Exp $ // GEANT4 tag $Name: geant4-04-00-patch-02 $ // // ----------------------------------------------------------------------- // This is an example of an application of GEANT4 to beam physics, which // makes use of the beam physics tools developed by the CPD at Fermilab: // CPDBeams. MuCool is a simulation of an accelerator section (The Double // Flip Cooling Channel) of a Neutrino Source design. It reduces the // transverse size and momentum of a muon beam using a technique known as // ionization cooling. For more information see note # 203 at URL: // // http://www-mucool.fnal.gov/notes/mcnoteSelMin.html // // Modified: V.Daniel Elvira // Date: April 16th 2002 // ----------------------------------------------------------------------- #include // RunManager controls the flow of the program and manages the event loop // within a run. TransportationManager stores the navigator used by the // transportation process to do the geometrical tracking. It also stores a // pointer to the propagator used in a magnetic field an the field manager. #include "G4RunManager.hh" #include "G4TransportationManager.hh" // MuCooldataCards is a global class used to provide input parameters to the // simulation. #include "MuCooldataCards.hh" // FieldManager, Field (the base field class), and the user field classes // are necessary to access the field and change modes (reference particle // or normal run) #include "G4FieldManager.hh" #include "G4Field.hh" #include "BTGlobalMagField.hh" #include "BTGlobalEMField.hh" // Physics user class. The associated messenger is needed to manipulate // multiple scattering, and the Muon Ionization class to manipulate // energy fluctuations in the energy loss process. #include "MuCoolPhysicsList.hh" #include "MuCoolPhysicsListMessenger.hh" #include "G4MuIonisation.hh" // User classes must be set to construct the accelerator (detectors), // generate the beam, manipulate tracks, perform actions at the end of a step, // or manipulate events. #include "MuCoolConstruct.hh" #include "MuCoolPrimaryGeneratorAction.hh" #include "MuCoolTrackingAction.hh" #include "MuCoolSteppingAction.hh" #include "MuCoolEventAction.hh" // If ROOTFLAG is set, then the root headers necessary to create histos and // ntuples are compiled. #ifdef ROOTFLAG #include "TROOT.h" #include "TFile.h" #include "TNtuple.h" #include "TH1.h" #include "TH2.h" #endif // The ZMtimer class allows to perform cpu timing studies. #define FIXED_TYPES_ENV 1 #include "ZMtools/ZMtimer.h" // If G4VIS_USE is set, then the headers necessary to visualize the geometry // elements with OpenInventor are compiled. #ifdef G4VIS_USE #include "MuCoolVisManager.hh" #include "G4UImanager.hh" #include "G4UIterminal.hh" #include "G4UIXm.hh" #endif // Create a global object MyDataCards of type data cards MuCooldataCards MyDataCards; // The BTSensDetGrid class allows to construct a grid of sensitive // detectors along the channel to define the sampling regions, i.e. the // position where ntuples are filled. It is global to allow access from // both the MuCoolConstruct and the MuCoolSteppingAction user hooks. BTSensDetGrid *Dets[500]; G4int TotNumDets; // mode is a global string which handles the three different run modes: // VISUAL, MACRO, and HARD. std::string mode; G4double weight; int main(int argc, char **argv) { char *inputFileDataCard; // This simulation code will take exactly three arguments: the code name // (MuCool), the running mode which can be visualization (VISUAL), // interactive (MACRO), or batch (HARD). if (argc > 2) { inputFileDataCard = argv[1]; if (MyDataCards.readKeys(inputFileDataCard) == 0) { cout << "Data Card File " << inputFileDataCard << " not found" << endl; exit(2); } } else { cout << "You must supply args: MuCool MuCool.in VISUAL (visual mode)" << endl; cout << " MuCool MuCool.in MACRO MuCool.mac (macro mode)" << endl; cout << " MuCool MuCool.in HARD (hard-code mode)" << endl; exit(2); } // Open ROOT file where histograms and ntuples are stored #ifdef ROOTFLAG TROOT data("data","Double Flip Channel"); std::string fileROOTout = MyDataCards.fetchValueString("ROOTFileName"); TFile *rtfile = new TFile(fileROOTout.c_str(), "RECREATE"); #endif // get the pointer to the UI manager and set verbosities // Use the user interface commands provided by the GEANT4 library. G4UImanager* UI = G4UImanager::GetUIpointer(); UI->ApplyCommand("/run/verbose 0"); UI->ApplyCommand("/event/verbose 0"); G4int vL = (G4int) MyDataCards.fetchValueDouble("verboseTrackingLevel"); char line[80]; sprintf (line, "/tracking/verbose %d", vL); UI->ApplyCommand(line); // Construct the default run manager G4RunManager* runManager = new G4RunManager; // set mandatory initialization classes MuCoolConstruct *detector = new MuCoolConstruct(); runManager->SetUserInitialization(detector); cout << " Processing MuCool Example (Double Flip Channel) " << endl; MuCoolPhysicsList *physList = new MuCoolPhysicsList(); runManager->SetUserInitialization(physList); // set mandatory user action class runManager->SetUserAction(new MuCoolPrimaryGeneratorAction); runManager->SetUserAction(new MuCoolTrackingAction); MuCoolSteppingAction* stepAct = new MuCoolSteppingAction; runManager->SetUserAction(stepAct); runManager->SetUserAction(new MuCoolEventAction); // Set particle production thresholds explicitly to default values. // Use the user interface commands defined BY THE USER in the // MuCoolPhysicsListMessenger class. UI->ApplyCommand("/range/cutG 2 mm"); UI->ApplyCommand("/range/cutE 2 mm"); // Initialize G4 kernel runManager->Initialize(); G4int numberOfEvent; G4double dNum = MyDataCards.fetchValueDouble("numEvts"); numberOfEvent = (G4int) dNum; std::string rfType = MyDataCards.fetchValueString("rfCellType"); G4bool hasRF = (rfType != "none"); // If the simulation contains an r.f. system, it is necessary to tune // the cavity phases by shooting a reference particle before runing the // beam. Stochastic processes, like multiple scattering, straggling, and // beta rays should be turned off during the reference particle run. if (hasRF) { // access the field G4FieldManager* fieldMgr = G4TransportationManager::GetTransportationManager() ->GetFieldManager(); const G4Field *aField = fieldMgr->GetDetectorField(); BTGlobalEMField *aEMField = (BTGlobalEMField *) aField; aEMField->SetModeRFRefParticle(); // Turn off Delta Rays, using UI commands implemente by the user in // the MuCoolPhysicsListMessenger class. This is done indirectly by // setting the production of secondary particles cut in range so high // that the primary particle never emmits secondaries. UI->ApplyCommand("/range/cutG 1 km"); UI->ApplyCommand("/range/cutE 1 km"); // Re-initialize G4 kernel with new particle range cuts. runManager->Initialize(); // Turn off Multiple scattering, using a UI command provided by // the GEANT4 library. UI->ApplyCommand("/process/inactivate msc"); // Turn off straggling while setting the rf phases. physList->theMuMinusIonisationf()->SetEnlossFluc(false); physList->theMuPlusIonisationf()->SetEnlossFluc(false); // Run reference particle runManager->BeamOn(1); // set r.f. system to normal mode (beam) aEMField->PrintLinacCells(); aEMField->SetModeRFNormal(); } // Now we prepare to run the beam through the simulation G4bool noStochastics = ( ((G4int) MyDataCards.fetchValueDouble("NoStochastics")) == 1); if (noStochastics == false ) { // Turn on Delta Rays, using a UI command provided by // the GEANT4 library. Indiretly by setting the cut in range for secondary // particles production to a low value. UI->ApplyCommand("/range/cutG 2 mm"); UI->ApplyCommand("/range/cutE 2 mm"); // Turn on Multiple scattering UI->ApplyCommand("/process/activate msc"); // Turn on straggling physList->theMuMinusIonisationf()->SetEnlossFluc(true); physList->theMuPlusIonisationf()->SetEnlossFluc(true); // Re-initialize G4 kernel with new particle range cuts. runManager->Initialize(); } // Specific blocks associated to the three run modes. mode = argv[2][0]; switch (argv[2][0]){ #ifdef G4VIS_USE case 'V': { G4VisManager *visManager; visManager = new MuCoolVisManager; visManager->Initialize(); G4UIsession *session_vis = new G4UIterminal; UI->ApplyCommand("/control/execute prerun_vis.mac"); session_vis->SessionStart(); delete session_vis; delete visManager; break; } #endif #ifdef MACRO_USE case 'M': { ZMcpuTimer myTimer; myTimer.reset(); myTimer.start(); // Pass beam parameters associated with interactive mode G4UIsession *session = new G4UIterminal; G4String command = "/control/execute "; G4String macroname = argv[3]; UI->ApplyCommand(command+macroname); // Uncomment the following lines and comment the previous one in order // to hard wire the command submittion instead of reading the commands // from a GEANT4 macro file. //UI->ApplyCommand("/gun/particle mu+"); //UI->ApplyCommand("/gun/energy 100 MeV"); //UI->ApplyCommand("/gun/direction 0 0 1"); //UI->ApplyCommand("/gun/position 2 1 0 cm"); //UI->ApplyCommand("/run/beamOn 1"); myTimer.stop(); cout << "cpuTime= " << myTimer.cpuTime() << endl; delete session; break; } #endif case 'H': { // hard-code session, no visualization. ZMcpuTimer myTimer; myTimer.reset(); myTimer.start(); runManager->BeamOn(numberOfEvent); myTimer.stop(); cout << "cpuTime= " << myTimer.cpuTime() << endl; break; } default: cout << "Invalid argument: mode options are VISUAL, MACRO, or HARD" << endl; exit(2); } cout <<"Simulation Completed" << endl; #ifdef ROOTFLAG rtfile->Write(); #endif delete runManager; return 0; }