// ExR01Histograms.cc // 25-Aug-99 Bill Seligman // This is an example class for booking histograms in GEANT4. #include "ExR01Histograms.hh" // Include the CLHEP Histogram classes #include "CLHEP/Hist/Histogram.h" #include "CLHEP/Hist/Tuple.h" #include "CLHEP/Hist/HBookFile.h" // For the random numbers in the StepFill example. #include "Randomize.hh" #include "globals.hh" // These are needed because they're arguments to the methods in // the RecorderBase class that we plan to use. In real life, we // might use the variables in G4Run or G4Step to // histogram or otherwise record values. #include "G4Run.hh" #include "G4Step.hh" // Let's be neat. Make sure that hfile is deleted even if the // the EndOfRun is never called. ExR01Histograms::ExR01Histograms() { hfile = NULL; } ExR01Histograms::~ExR01Histograms() { if (hfile != NULL) { delete hfile; } } void ExR01Histograms::RecordBeginOfRun(const G4Run* r) { // Open a new HBook file. // Side note: In my experience, it's not possible to open more than // one CLHEP HBookFile in a program at once, even if you give them unique // names and FORTRAN I/O numbers. if (hfile != NULL) delete hfile; // make sure the object doesn't exist. int lun = 66; // Fortran I/O unit number hfile = new HBookFile("example.hbook",lun); // Number of histogram bins int nBins1d = 100; int nBins2d = 40; // Limits for values double low = 0, high = 1; double xlow = 0, xhigh = 1, ylow = 0, yhigh = 1; // Histogram IDs. int id1D = 100; int id2D = 201; // A couple of notes: // 1) CLHEP tells whether you're creating a 1D or 2D histogram by looking // at the number and type of arguments to the histogram routine. // 2) If we had not chosen to supply a histogram ID, the HBookFile class // will choose it for us. This is not a good idea; you should supply the ID. // 3) If a histogram with the given title does not already exist, the "histogram" // routine will create it and return a point to the new histogram. If a // histogram with the given title already exists, "histogram" will return a pointer // that histogram; it will not overwrite the existing one. myHisto1D = hfile->histogram("HepJamesRandom1", nBins1d, low, high, id1D); myHisto2D = hfile->histogram("HepJamesVsDRand48", nBins2d, xlow, xhigh, nBins2d, ylow, yhigh, id2D); // The same general ideas apply to ntuples: int ntID = 1000; myTuple = hfile->ntuple("RandomNumbers",ntID); } void ExR01Histograms::RecordEndOfRun(const G4Run* r) { // Write the contents of the HBookFile. hfile->write(); // We created it with "new", so we have to destroy it with "delete": delete hfile; hfile = NULL; // Make sure that we'll recognize that it's been deleted. } void ExR01Histograms::RecordStep(const G4Step*) { // Generate random numbers using two different CLHEP "engines". // Accumulate the results of the James Engine in the 1-d histogram; // accumulate the results of the James versus "Rand48" in the // 2-d histogram. HepRandom::setTheEngine(&theJamesEngine); double james = RandGauss::shoot(0.3,0.1); myHisto1D->accumulate(james,0.01); HepRandom::setTheEngine(&theDRand48Engine); double d48 = RandGauss::shoot(0.7,0.1); myHisto2D->accumulate(james,d48,0.01); // Add the random numbers to the ntuple. The first time // the column method is called, it creates the column. Each // subsequent call adds to the column. Once all the columns // are filled, you must call dumpData to add the information // to the ntuple. myTuple->column("James",james); myTuple->column("Rand48",d48); myTuple->dumpData(); }