Spectrometer Toolkit for ROOT

Author:
Bino Maiheu, University College London

Sergey Kostromin, Joint Institute for Nuclear Research, Dubna

This set of source files contain ROOT macros to handle spectrometer energy calculations for the ILC test chicane at ESA and for ILC spectrometer simulations. The aim is to provide a complete set of routines used for simulations and data calculation for everyone to base their analysis upon.

Here are the different source files and links to the documentation of the routines :

Handy analysis of spectrometer data can be setup using a virtual spectrometer class, for which the user him/herself has to map the data to the specific ROOT tree layout.

How to get it...

You can download the latest version from CVS at the following location:

http://cvs.hep.ucl.ac.uk/viewcvs/spectrometer/root-macros/?root=ILC+Accelerator+code

Please click on "Download a GNU tarball" on that page to obtain the sources. Just untar it and go to that directory, as there is a rootlogon.C present in the distribution, firing up ROOT from that directory will automatically compile the classes and functions into the ROOT session.

For examples, check out the analysis subdirectory where you will find some examples of pratical application of these functions and classes.

Documentation...

To generate this documentation, either in HTML or PDF forms, just run doxgen with the doxygen.cfg configuration file from the top level directory. This will create the documentation subdir with the doxygen reference.

Example analysis code...

There you can see an example analysis code which runs over simulated spectrometer data. It first constructs the simulatedSpectrometer class, derived from the TVirtualSpectrometer. And then takes 3 files that were generated with the Geant4 spectrometer simulation program. One at 0 field to get the alignment, and one at +B and -B.

   #include <TFile.h>
   #include "TVirtualSpectrometer.h"
   #include "spectrometerGlobals.h"
   #include "spectrometerEsaParameters.h"

   class simulatedSpectrometer : public TVirtualSpectrometer {
   public:
     simulatedSpectrometer( Int_t nOrbitBPMs, Int_t nChicaneBPMs );
     ~simulatedSpectrometer();

     Int_t setTree( TTree *t );
     Int_t getEvent( Long64_t iev );

     Double_t getSimEnergy( Long64_t iev );

   private:
     Long64_t  _iEvCurrent;  // currently loaded event number

     Double_t  _xpos[8];
     Double_t  _ypos[8];
     Double_t  _energy[8];

     ClassDef( simulatedSpectrometer, 1 )
   };

   // ----------------------------------------------------------------------------
   ClassImp( simulatedSpectrometer )

   simulatedSpectrometer::simulatedSpectrometer( Int_t nOrbitBPMs, Int_t nChicaneBPMs ) : 
     TVirtualSpectrometer( nOrbitBPMs, nChicaneBPMs ) {

     // set the orbit BPM positions
     _zOrbitPos[0]   = 13.557;
     _zOrbitPos[1]   = 14.889;
     _zOrbitPos[2]   = 30.914;
     _zOrbitPos[3]   = 31.943;

     // set the chicane BPM positions
     _zChicanePos[0] = 38.189;

     // set currently loaded event number to -1
     _iEvCurrent = -1;
   }

   // ----------------------------------------------------------------------------

   simulatedSpectrometer::~simulatedSpectrometer( ){ } 

   // ----------------------------------------------------------------------------

   Int_t simulatedSpectrometer::setTree( TTree *t ) {

     // set tree
     _dataTree = t;

     // book variables
     t->SetBranchAddress( "xpos", _xpos );
     t->SetBranchAddress( "ypos", _ypos );

     // book the simulated energy variable
     t->SetBranchAddress( "energy", _energy );

     return 0;
   }

   // ----------------------------------------------------------------------------

   Int_t simulatedSpectrometer::getEvent( Long64_t iev ) {

     if ( iev != _iEvCurrent ) {  // avoid TTree::GetEntry() when not needed
       // get the entry
       _dataTree->GetEntry( iev );

       // set the events + make sure units are in meter for the positions !!!
       _xOrbitPos[0]   = _xpos[0]*1.0e-3;
       _xOrbitPos[1]   = _xpos[1]*1.0e-3;
       _xOrbitPos[2]   = _xpos[2]*1.0e-3;
       _xOrbitPos[3]   = _xpos[3]*1.0e-3;
    
       _xChicanePos[0] = _xpos[4]*1.0e-3;
    
       _iEvCurrent = iev;
     }

     return 0;
   }

   // ----------------------------------------------------------------------------

   Double_t simulatedSpectrometer::getSimEnergy( Long64_t iev ) {
     if ( this->getEvent( iev ) ) return 0.;
     return _energy[0];
   }

   // ----------------------------------------------------------------------------
   //                           This is the main function
   // ----------------------------------------------------------------------------

   void simulationRun( void ) {

     TFile *f0 = new TFile ( "esa-chicane-mar07-zero-1.root" );
     TFile *f1 = new TFile ( "esa-chicane-mar07-plusB-1.root" );
     TFile *f2 = new TFile ( "esa-chicane-mar07-minusB-1.root" );

     TTree *t0 = (TTree*) f0->Get( "bpmhits" );
     TTree *t1 = (TTree*) f1->Get( "bpmhits" );
     TTree *t2 = (TTree*) f2->Get( "bpmhits" );
  
     simulatedSpectrometer *espec = new simulatedSpectrometer( 4, 1 );
     espec->setMagnetLocations( EsaMag1ZPos, EsaMag2ZPos );

     std::cout << "+++ Aligning spectrometer from zero field data" << std::endl;
     espec->setTree( t0 );
     espec->alignSystem( 1, 2000, alignMode_Linear );
     espec->showAlignment();

     std::cout << "+++ Running over file with +B" << std::endl;
     espec->setTree( t1 );
     espec->setMagnetFields( -0.115, 0.115 );
     for ( int i = 0; i < 10; i++ ) {
       std::cout << "Pulse " << i 
                 << ", measured  = " << espec->getEnergy( i ) 
                 << ", simulated = " << espec->getSimEnergy( i ) << " GeV" 
                 << ", deltaE/E = " 
                 << (espec->getEnergy( i )-espec->getSimEnergy( i ))/espec->getSimEnergy( i ) 
                 << std::endl;
     }

     std::cout << "+++ Running over file with -B" << std::endl;
     espec->setTree( t2 );
     espec->setMagnetFields( 0.115, -0.115 );
     for ( int i = 0; i < 10; i++ ) {
       std::cout << "Pulse " << i 
                 << ", measured  = " << espec->getEnergy( i ) 
                 << ", simulated = " << espec->getSimEnergy( i ) << " GeV"
                 << ", deltaE/E = " 
                 << (espec->getEnergy( i )-espec->getSimEnergy( i ))/espec->getSimEnergy( i ) 
                 << std::endl;
     }
     return;
   }

To load this example, fire up ROOT in the top level directory and compile the analysis macro into the session using

   root [0] gSystem->CompileMacro( "spectrometer-sim.C" )
   

Running the simulationRun() function over "spectrometer" simulated data yields an output like :

   root [1] simulationRun()                              
   +++ Aligning spectrometer from zero field data
   Aligning spectrometer, hope you're at 0 field :)...
   Used 100 % of the requested events for the alignment constants
    -- Mean position Orbit BPM [0] = 0.0755154 mm
    -- Mean position Orbit BPM [1] = -0.114493 mm
    -- Mean position Orbit BPM [2] = -0.0544941 mm
    -- Mean position Orbit BPM [3] = 0.0704953 mm
    -- Mean position Chicane BPM [0] = -0.0444983 mm
   Spectrometer aligned using linear orbit fit
    * Established null orbit with Orbit BPMs, offsets : 
      - Orbit BPM[0] offset = 0.0940582 mm
      - Orbit BPM[1] offset = -0.0977892 mm
      - Orbit BPM[2] offset = -0.0599187 mm
      - Orbit BPM[3] offset = 0.0636497 mm
      - Chicane BPM[0] offset from above orbit = -0.0599686 mm
   +++ Running over file with +B
   Pulse 0, measured  = 34.067, simulated = 34.0608 GeV, deltaE/E = 0.000182628
   Pulse 1, measured  = 28.1609, simulated = 28.1585 GeV, deltaE/E = 8.69246e-05
   Pulse 2, measured  = 32.1094, simulated = 32.1075 GeV, deltaE/E = 6.13955e-05
   Pulse 3, measured  = 23.2807, simulated = 23.2835 GeV, deltaE/E = -0.000116418
   Pulse 4, measured  = 26.3032, simulated = 26.3101 GeV, deltaE/E = -0.000260183
   Pulse 5, measured  = 27.686, simulated = 27.6815 GeV, deltaE/E = 0.000163069
   Pulse 6, measured  = 29.804, simulated = 29.8043 GeV, deltaE/E = -1.03562e-05
   Pulse 7, measured  = 28.543, simulated = 28.5433 GeV, deltaE/E = -1.31636e-05
   Pulse 8, measured  = 27.38, simulated = 27.3857 GeV, deltaE/E = -0.000210192
   Pulse 9, measured  = 28.2667, simulated = 28.2755 GeV, deltaE/E = -0.00031217
   +++ Running over file with -B
   Pulse 0, measured  = 34.0545, simulated = 34.0608 GeV, deltaE/E = -0.000183494
   Pulse 1, measured  = 28.156, simulated = 28.1585 GeV, deltaE/E = -8.82544e-05
   Pulse 2, measured  = 32.1054, simulated = 32.1075 GeV, deltaE/E = -6.2425e-05
   Pulse 3, measured  = 23.2861, simulated = 23.2835 GeV, deltaE/E = 0.0001145
   Pulse 4, measured  = 26.3169, simulated = 26.3101 GeV, deltaE/E = 0.000258791
   Pulse 5, measured  = 27.6769, simulated = 27.6815 GeV, deltaE/E = -0.000164404
   Pulse 6, measured  = 29.8046, simulated = 29.8043 GeV, deltaE/E = 9.15413e-06
   Pulse 7, measured  = 28.5437, simulated = 28.5433 GeV, deltaE/E = 1.18537e-05
   Pulse 8, measured  = 27.3915, simulated = 27.3857 GeV, deltaE/E = 0.00020886
   Pulse 9, measured  = 28.2843, simulated = 28.2755 GeV, deltaE/E = 0.000311029
   

For comments and feedback, please drop Bino a line :)


Generated on Fri Dec 14 15:55:25 2007 for spectrometer by  doxygen 1.5.1