Index: /trunk/Utilities/ExRootAnalysis/CREDITS
===================================================================
--- /trunk/Utilities/ExRootAnalysis/CREDITS	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/CREDITS	(revision 3)
@@ -0,0 +1,1 @@
+Pavel Demin
Index: /trunk/Utilities/ExRootAnalysis/VERSION
===================================================================
--- /trunk/Utilities/ExRootAnalysis/VERSION	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/VERSION	(revision 3)
@@ -0,0 +1,1 @@
+1.0.6
Index: /trunk/Utilities/ExRootAnalysis/interface/BlockClasses.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/BlockClasses.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/BlockClasses.h	(revision 3)
@@ -0,0 +1,330 @@
+#ifndef BLOCKCLASSES_H
+#define BLOCKCLASSES_H
+
+/** \class BlockClasses
+ *
+ *  Definition of classes to be stored in root tree.  
+ *  You can decide to have the objects in each event to be sorted according 
+ *  to one of the data member of the class. If you decide so then a class 
+ *  inheriting from class TCompare should be implemented. 
+ *  There are already several functions TCompare*** implemented 
+ *  (see BlockCompare.h). 
+ *  Function TCompareXX sorts objects by the variable "XX" that MUST be 
+ *  present in the data members of the Block TRoot class.
+ *
+ *  $Date: 2008-11-04 10:32:25 $
+ *  $Revision: 1.1 $
+ *
+ *  
+ *  \author P. Demin - UCL, Louvain-la-Neuve
+ *
+ */
+
+// Dependencies (#includes)
+
+#include "TLorentzVector.h"
+#include "TRef.h"
+#include "TObject.h"
+#include "TRefArray.h"
+
+#include "Utilities/ExRootAnalysis/interface/BlockCompare.h"
+//---------------------------------------------------------------------------
+//
+class TSortableObject: public TObject
+{
+public:
+  TSortableObject() {};
+  Bool_t IsSortable() const { return GetCompare() ? GetCompare()->IsSortable(this) : kFALSE; }
+  Int_t Compare(const TObject *obj) const { return GetCompare()->Compare(this, obj); }
+
+  virtual const TCompare *GetCompare() const = 0;
+
+  ClassDef(TSortableObject, 1)
+};
+
+
+//---------------------------------------------------------------------------
+//
+class TRootLHEFEvent: public TObject
+{
+public:
+  TRootLHEFEvent() {};
+
+  Long64_t Number; // event number
+
+  int Nparticles; // number of particles in the event | hepup.NUP
+  int ProcessID; // subprocess code for the event | hepup.IDPRUP
+
+  Double_t Weight; // weight for the event | hepup.XWGTUP
+  Double_t ScalePDF; // scale in GeV used in the calculation of the PDFs in the event | hepup.SCALUP
+  Double_t CouplingQED; // value of the QED coupling used in the event | hepup.AQEDUP
+  Double_t CouplingQCD; // value of the QCD coupling used in the event | hepup.AQCDUP
+
+  ClassDef(TRootLHEFEvent, 2)
+};
+
+//---------------------------------------------------------------------------
+
+class TRootLHEFParticle: public TSortableObject
+{
+public:
+  TRootLHEFParticle() {};
+  int PID; // particle HEP ID number | hepup.IDUP[number]
+  int Status; // particle status code | hepup.ISTUP[number]
+  int Mother1; // index for the particle first mother | hepup.MOTHUP[number][0]
+  int Mother2; // index for the particle last mother | hepup.MOTHUP[number][1]
+  int ColorLine1; // index for the particle color-line | hepup.ICOLUP[number][0]
+  int ColorLine2; // index for the particle anti-color-line | hepup.ICOLUP[number][1]
+
+  Double_t Px; // particle momentum vector (x component) | hepup.PUP[number][0]
+  Double_t Py; // particle momentum vector (y component) | hepup.PUP[number][1]
+  Double_t Pz; // particle momentum vector (z component) | hepup.PUP[number][2]
+  Double_t E; // particle energy | hepup.PUP[number][3]
+  Double_t M; // particle mass | hepup.PUP[number][4]
+
+  Double_t PT; // particle transverse momentum
+  Double_t Eta; // particle pseudorapidity
+  Double_t Phi; // particle azimuthal angle
+
+  Double_t Rapidity; // particle rapidity
+
+  Double_t LifeTime; // particle invariant lifetime
+                     // (c*tau, distance from production to decay in mm)
+                     // | hepup.VTIMUP[number]
+                     
+  Double_t Spin; // cosine of the angle between the particle spin vector
+                 // and the decaying particle 3-momentum,
+                 // specified in the lab frame. | hepup.SPINUP[number]
+
+  static TCompare *fgCompare; //!
+  const TCompare *GetCompare() const { return fgCompare; }
+  ClassDef(TRootLHEFParticle, 2)
+
+};
+
+//---------------------------------------------------------------------------
+
+class TRootSelectorInfo: public TObject
+{
+public:
+  TRootSelectorInfo() {};
+  int Processed; // current number of processed events
+  int Accepted; // current number of accepted events
+
+  ClassDef(TRootSelectorInfo, 1)
+};
+
+
+class TRootGenEvent: public TObject
+{
+public:
+  TRootGenEvent() {};
+  Long64_t Number; // event number | hepevt.nevhep
+
+  static TCompare *fgCompare; //!
+  const TCompare *GetCompare() const { return fgCompare; }
+
+  ClassDef(TRootGenEvent, 1)
+};
+
+
+class TRootEvent: public TObject {
+
+public:
+  TRootEvent() {};
+  int Run; // run number [G3EventProxy::simSignal().id().runNumber()]
+  int Event; // event number [G3EventProxy::simSignal().id().eventInRun()]
+
+//  Short_t L1Decision; // L1 trigger global decision [L1Trigger::decision()]
+//  Short_t HLTDecision; // HLT trigger global decision [HighLevelTriggerResult::getGlobalDecision()]
+
+  ClassDef(TRootEvent, 1)
+};
+
+//---------------------------------------------------------------------------
+
+class TRootParticle: public TSortableObject {
+
+public:
+
+  TRootParticle() {};
+  float E;  // particle energy in GeV
+  float Px; // particle momentum vector (x component) in GeV
+  float Py; // particle momentum vector (y component) in GeV
+  float Pz; // particle momentum vector (z component) in GeV
+
+  float PT; // particle transverse momentum in GeV
+  float Eta; // particle pseudorapidity  
+  float Phi; // particle azimuthal angle in rad 
+
+  void Set(const TLorentzVector& momentum);
+  static TCompare *fgCompare; //!
+  const TCompare *GetCompare() const { return fgCompare; }
+
+  ClassDef(TRootParticle, 1)
+};
+
+
+//---------------------------------------------------------------------------
+
+class TRootGenParticle: public TRootParticle {
+
+public:
+  TRootGenParticle() {};
+  int PID; // particle HEP ID number [RawHepEventParticle::pid()]
+  int Status; // particle status [RawHepEventParticle::status()]
+  int M1; // particle 1st mother [RawHepEventParticle::mother1() - 1]
+  int M2; // particle 2nd mother [RawHepEventParticle::mother2() - 1]
+  int D1; // particle 1st daughter [RawHepEventParticle::daughter1() - 1]
+  int D2; // particle 2nd daughter [RawHepEventParticle::daughter2() - 1]
+  float Charge; // electrical charge
+
+  float T; // particle vertex position (t component) [RawHepEventParticle::t()]
+  float X; // particle vertex position (x component) [RawHepEventParticle::x()]
+  float Y; // particle vertex position (y component) [RawHepEventParticle::y()]
+  float Z; // particle vertex position (z component) [RawHepEventParticle::z()]
+  static TCompare *fgCompare; //!
+
+  ClassDef(TRootGenParticle, 1)
+};
+
+//------------------------------------------------------------------------------
+
+class TRootElectron: public TRootParticle
+{
+public:
+  TRootElectron() {};
+  int Charge; // particle Charge [RawHepEventParticle::pid()]
+  static TCompare *fgCompare; //!
+
+  ClassDef(TRootElectron, 1)
+};
+
+//------------------------------------------------------------------------------
+
+class TRootPhoton: public TRootParticle
+{
+public:
+  TRootPhoton() {};
+  static TCompare *fgCompare; //!
+
+  ClassDef(TRootPhoton, 1)
+};
+
+
+//------------------------------------------------------------------------------
+
+class TRootMuon: public TRootParticle
+{
+public:
+  TRootMuon() {};
+  int Charge; // particle Charge [RawHepEventParticle::pid()]
+  static TCompare *fgCompare; //!
+
+  ClassDef(TRootMuon, 1)
+};
+
+//---------------------------------------------------------------------------
+
+class TRootTracks: public TRootParticle
+{
+public:
+  TRootTracks() {};
+  static TCompare *fgCompare; //!
+
+  ClassDef(TRootTracks, 1)
+};
+
+//---------------------------------------------------------------------------
+
+class TRootCalo: public TRootParticle
+{
+public:
+  TRootCalo() {};
+  static TCompare *fgCompare; //!
+
+  ClassDef(TRootCalo, 1)
+};
+
+//---------------------------------------------------------------------------
+class TRootZdcHits: public TRootParticle
+{
+public:
+  TRootZdcHits() {};
+  float T; // time of flight [s]
+  int side; // -1 or +1
+  static TCompare *fgCompare; //!
+
+  ClassDef(TRootZdcHits, 1)
+};
+
+//---------------------------------------------------------------------------
+
+class TRootJet: public TRootParticle
+{
+public:
+  TRootJet() {};
+  bool Btag;
+
+  static TCompare *fgCompare; //!
+  
+  ClassDef(TRootJet, 1)
+};
+
+//---------------------------------------------------------------------------
+
+class TRootTauJet: public TRootParticle
+{
+public:
+  TRootTauJet() {};
+  static TCompare *fgCompare; //!
+
+  ClassDef(TRootTauJet, 1)
+};
+
+//---------------------------------------------------------------------------
+
+class TRootETmis: public TSortableObject
+{
+public:
+  TRootETmis() {};
+  float ET; // jet energy [RecJet::getEnergy()]
+  float Phi; // jet azimuthal angle [RecJet::getPhi()]
+  float Px;
+  float Py;
+
+  static TCompare *fgCompare; //!
+  const TCompare *GetCompare() const { return fgCompare; }
+
+  ClassDef(TRootETmis, 1)
+};
+
+//---------------------------------------------------------------------------
+
+class TRootRomanPotHits: public TSortableObject
+{
+public:
+  TRootRomanPotHits() {};
+  float T; // time of flight to the detector [s]
+  float S; // distance to the IP [m]
+  float E; // reconstructed energy [GeV]
+  float q2; // reconstructed squared momentum transfer [GeV^2]
+
+  float X; // horizontal distance to the beam [um]
+  float Y; // vertical distance to the beam [um]
+
+  float Tx; // angle of the momentum in the horizontal (x,z) plane [urad]
+  float Ty; // angle of the momentum in the verical (y,z) plane [urad]
+
+  int side; // -1 or 1
+
+  static TCompare *fgCompare; //!
+  const TCompare *GetCompare() const { return fgCompare; }
+
+  ClassDef(TRootRomanPotHits, 1)
+};
+
+//---------------------------------------------------------------------------
+
+#endif // BLOCKCLASSES_H
+
Index: /trunk/Utilities/ExRootAnalysis/interface/BlockCompare.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/BlockCompare.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/BlockCompare.h	(revision 3)
@@ -0,0 +1,225 @@
+#ifndef BLOCKCOMPARE_H
+#define BLOCKCOMPARE_H
+
+/** \class BlockCompare
+ *
+ *  Definition of comparison object functions for block classes
+ *
+ *  $Date: 2008-11-04 10:32:25 $
+ *  $Revision: 1.1 $
+ *
+ *  
+ *  \author S. Ovyn - UCL, Louvain-la-Neuve
+ *
+ */
+
+// Dependencies (#includes)
+
+#include "Rtypes.h"
+#include "TMath.h"
+
+//------------------------------------------------------------------------------
+
+class TObject;
+
+class TCompare
+{
+public:
+  virtual Bool_t IsSortable(const TObject *obj) const { return kTRUE; }
+  virtual Int_t Compare(const TObject *obj1, const TObject *obj2) const = 0;
+  virtual ~TCompare() {};
+};
+
+//---------------------------------------------------------------------------
+
+template <typename T>
+class TCompareE: public TCompare
+{
+  TCompareE() {}
+public:
+  static TCompareE *Instance()
+  {
+    static TCompareE single;
+    return &single;
+  }
+
+  Int_t Compare(const TObject *obj1, const TObject *obj2) const
+  {
+    const T *t1 = static_cast<const T*>(obj1);
+    const T *t2 = static_cast<const T*>(obj2);
+    if(t1->E > t2->E)
+      return -1;
+    else if(t1->E < t2->E)
+      return 1;
+    else
+      return 0;
+  }
+};
+
+//---------------------------------------------------------------------------
+
+template <typename T>
+class TComparePT: public TCompare
+{
+  TComparePT() {}
+public:
+  static TComparePT *Instance()
+  {
+    static TComparePT single;
+    return &single;
+  }
+
+  Int_t Compare(const TObject *obj1, const TObject *obj2) const
+  {
+    const T *t1 = static_cast<const T*>(obj1);
+    const T *t2 = static_cast<const T*>(obj2);
+    if(t1->PT > t2->PT)
+      return -1;
+    else if(t1->PT < t2->PT)
+      return 1;
+    else
+      return 0;
+  }
+};
+
+//---------------------------------------------------------------------------
+
+template <typename T>
+class TCompareET: public TCompare
+{
+  TCompareET() {}
+public:
+  static TCompareET *Instance()
+  {
+    static TCompareET single;
+    return &single;
+  }
+
+  Int_t Compare(const TObject *obj1, const TObject *obj2) const
+  {
+    const T *t1 = static_cast<const T*>(obj1);
+    const T *t2 = static_cast<const T*>(obj2);
+    if(t1->ET > t2->ET)
+      return -1;
+    else if(t1->ET < t2->ET)
+      return 1;
+    else
+      return 0;
+  }
+};
+
+//---------------------------------------------------------------------------
+
+template <typename T>
+class TCompareCalPT: public TCompare
+{
+  TCompareCalPT() {}
+public:
+  static TCompareCalPT *Instance()
+  {
+    static TCompareCalPT single;
+    return &single;
+  }
+
+  Int_t Compare(const TObject *obj1, const TObject *obj2) const
+  {
+    const T *t1 = static_cast<const T*>(obj1);
+    const T *t2 = static_cast<const T*>(obj2);
+    if(t1->CalPT > t2->CalPT)
+      return -1;
+    else if(t1->CalPT < t2->CalPT)
+      return 1;
+    else
+      return 0;
+  }
+};
+
+
+//---------------------------------------------------------------------------
+
+template <typename T>
+class TCompareCalET: public TCompare
+{
+  TCompareCalET() {}
+public:
+  static TCompareCalET *Instance()
+  {
+    static TCompareCalET single;
+    return &single;
+  }
+
+  Int_t Compare(const TObject *obj1, const TObject *obj2) const
+  {
+    const T *t1 = static_cast<const T*>(obj1);
+    const T *t2 = static_cast<const T*>(obj2);
+    if(t1->CalET > t2->CalET)
+      return -1;
+    else if(t1->CalET < t2->CalET)
+      return 1;
+    else
+      return 0;
+  }
+};
+
+//---------------------------------------------------------------------------
+
+template <typename T1, typename T2>
+class TCompareDeltaR: public TCompare
+{
+  TCompareDeltaR(const T2 *obj = 0) : fObj(obj) {}
+
+  Float_t DeltaPhi(Float_t phi1, Float_t phi2)
+  {
+    Float_t phi = TMath::Abs(phi1 - phi2);
+    return (phi <= TMath::Pi()) ? phi : (2.0*TMath::Pi()) - phi;
+  }
+
+  Float_t Sqr(Float_t x) { return x*x; }
+
+  Float_t SumSqr(Float_t a, Float_t b)
+  {
+    Float_t aAbs = TMath::Abs(a);
+    Float_t bAbs = TMath::Abs(b);
+    if(aAbs > bAbs) return aAbs * TMath::Sqrt(1.0 + Sqr(bAbs / aAbs));
+    else return (bAbs == 0) ? 0.0 : bAbs * TMath::Sqrt(1.0 + Sqr(aAbs / bAbs));
+  };
+  
+  const T2 *fObj;
+  
+public:
+  static TCompareDeltaR *Instance(const T2 *obj = 0)
+  {
+    static TCompareDeltaR single(obj);
+    return &single;
+  }
+
+  void SetObject(const T2 *obj) { fObj = obj; }
+
+  Int_t Compare(const TObject *obj1, const TObject *obj2) const
+  {
+    Float_t eta[3], phi[3], deltaR[2];
+    const T1 *t1 = static_cast<const T1*>(obj1);
+    const T1 *t2 = static_cast<const T1*>(obj2);
+
+    eta[0] = fObj->Eta;
+    phi[0] = fObj->Phi;
+
+    eta[1] = t1->Eta;
+    phi[1] = t1->Phi;
+
+    eta[2] = t2->Eta;
+    phi[2] = t2->Phi;
+
+    deltaR[0] = SumSqr(TMath::Abs(eta[0] - eta[1]), DeltaPhi(phi[0], phi[1]));
+    deltaR[1] = SumSqr(TMath::Abs(eta[0] - eta[2]), DeltaPhi(phi[0], phi[2]));
+    
+    if(deltaR[0] < deltaR[1])
+      return -1;
+    else if(deltaR[0] > deltaR[1])
+      return 1;
+    else
+      return 0;
+  }
+};
+
+#endif // BLOCKCOMPARE_H
Index: /trunk/Utilities/ExRootAnalysis/interface/ExRootProgressBar.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/ExRootProgressBar.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/ExRootProgressBar.h	(revision 3)
@@ -0,0 +1,29 @@
+#ifndef ExRootProgressBar_h
+#define ExRootProgressBar_h
+
+#include "Rtypes.h"
+
+class ExRootProgressBar
+{
+public:
+
+  ExRootProgressBar(Long64_t entries, Int_t width = 25);
+  ~ExRootProgressBar();
+
+  void Update(Long64_t entry);
+  void Finish();
+
+private:
+
+  Long64_t fEntries;
+  Int_t fWidth;
+
+  ULong_t fTime;
+  Int_t fHashes;
+
+  char *fBar;
+
+};
+
+#endif /* ExRootProgressBar */
+
Index: /trunk/Utilities/ExRootAnalysis/interface/ExRootTreeBranch.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/ExRootTreeBranch.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/ExRootTreeBranch.h	(revision 3)
@@ -0,0 +1,41 @@
+#ifndef ExRootTreeBranch_h
+#define ExRootTreeBranch_h
+
+/** \class ExRootTreeBranch
+ *
+ *  Class handling output ROOT tree branch
+ *
+ *  $Date: 2008-11-04 10:32:26 $
+ *  $Revision: 1.1 $
+ *
+ *
+ *  \author S. Ovyn - UCL, Louvain-la-Neuve
+ *
+ */
+
+#include "Rtypes.h"
+#include "TString.h"
+
+class TTree;
+class TClonesArray;
+
+class ExRootTreeBranch
+{
+public:
+
+  class MemoryAllocationExeption{};
+  
+  ExRootTreeBranch(const TString &name, TClass *cl, TTree *tree);
+  ~ExRootTreeBranch();
+
+  TObject *NewEntry();
+  void Clear();
+
+private:
+
+  Int_t fSize, fCapacity;
+  TClonesArray *fData;  
+};
+
+#endif /* ExRootTreeBranch */
+
Index: /trunk/Utilities/ExRootAnalysis/interface/ExRootTreeReader.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/ExRootTreeReader.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/ExRootTreeReader.h	(revision 3)
@@ -0,0 +1,49 @@
+#ifndef ExRootTreeReader_h
+#define ExRootTreeReader_h
+
+/** \class ExRootTreeReader
+ *
+ *  Class simplifying access to ROOT tree branches
+ *
+ *  $Date: 2008-11-04 10:32:26 $
+ *  $Revision: 1.1 $
+ *
+ *
+ *  \author S. Ovyn - UCL, Louvain-la-Neuve
+ *
+ */
+
+#include "TROOT.h"
+#include "TChain.h"
+#include "TFile.h"
+
+#include <map>
+
+class ExRootTreeReader
+{
+public :
+
+  ExRootTreeReader(TTree *tree);
+  ~ExRootTreeReader();
+
+  Long64_t GetEntries() const { return fChain ? static_cast<Long64_t>(fChain->GetEntries()) : 0; }
+  Bool_t ReadEntry(Long64_t entry);
+
+  TClonesArray *UseBranch(const TString &branchName);
+
+private:
+
+  void Init();
+  void Notify();
+
+  TTree *fChain;  // pointer to the analyzed TTree or TChain
+  Int_t fCurrentTree; // current Tree number in a TChain
+
+  Bool_t fIsInitDone;
+
+  typedef std::map<TString, std::pair<TBranch*, TClonesArray*> > TBranchMap;
+
+  TBranchMap fBranchMap;
+};
+
+#endif // ExRootTreeReader_h
Index: /trunk/Utilities/ExRootAnalysis/interface/ExRootTreeWriter.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/ExRootTreeWriter.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/ExRootTreeWriter.h	(revision 3)
@@ -0,0 +1,47 @@
+#ifndef ExRootTreeWriter_h
+#define ExRootTreeWriter_h
+
+/** \class ExRootTreeWriter
+ *
+ *  Class handling output ROOT tree
+ *
+ *  $Date: 2008-11-04 10:32:26 $
+ *  $Revision: 1.1 $
+ *
+ *
+ *  \author S. Ovyn - UCL, Louvain-la-Neuve
+ *
+ */
+
+#include "TString.h"
+ 
+#include <set>
+
+class TFile;
+class TTree;
+class TClass;
+class ExRootTreeBranch;
+
+class ExRootTreeWriter
+{
+public:
+
+  ExRootTreeWriter(const TString &fileName, const TString &treeName = "Result");
+  ~ExRootTreeWriter();
+
+  ExRootTreeBranch *NewBranch(const TString &name, TClass *cl);
+
+  void Clear();
+  void Fill();
+  void Write();
+
+private:
+
+  TFile *fNewFile;
+  TTree *fNewTree;
+
+  std::set<ExRootTreeBranch*> fBranches;
+};
+
+#endif /* ExRootTreeWriter */
+
Index: /trunk/Utilities/ExRootAnalysis/interface/LHEF.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/LHEF.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/LHEF.h	(revision 3)
@@ -0,0 +1,897 @@
+// -*- C++ -*-
+#ifndef THEPEG_LHEF_H
+#define THEPEG_LHEF_H
+//
+// This is the declaration of the Les Houches Event File classes.
+//
+
+
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <utility>
+#include <stdexcept>
+
+namespace LHEF {
+
+/**
+ * The HEPRUP class is a simple container corresponding to the Les Houches
+ * accord (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>)
+ * common block with the same name. The members are named in the same
+ * way as in the common block. However, fortran arrays are represented
+ * by vectors, except for the arrays of length two which are
+ * represented by pair objects.
+ */
+class HEPRUP {
+
+public:
+
+  /** @name Standard constructors and destructors. */
+  //@{
+  /**
+   * Default constructor.
+   */
+  HEPRUP()
+    : IDWTUP(0), NPRUP(0) {}
+
+  /**
+   * Copy-constructor.
+   */
+  HEPRUP(const HEPRUP & x)
+    : IDBMUP(x.IDBMUP), EBMUP(x.EBMUP),
+      PDFGUP(x.PDFGUP), PDFSUP(x.PDFSUP), IDWTUP(x.IDWTUP),
+      NPRUP(x.NPRUP), XSECUP(x.XSECUP), XERRUP(x.XERRUP),
+      XMAXUP(x.XMAXUP), LPRUP(x.LPRUP) {}
+
+
+  /**
+   * Assignment operator.
+   */
+  HEPRUP & operator=(const HEPRUP & x) {
+    IDBMUP = x.IDBMUP;
+    EBMUP = x.EBMUP;
+    PDFGUP = x.PDFGUP;
+    PDFSUP = x.PDFSUP;
+    IDWTUP = x.IDWTUP;
+    NPRUP = x.NPRUP;
+    XSECUP = x.XSECUP;
+    XERRUP = x.XERRUP;
+    XMAXUP = x.XMAXUP;
+    LPRUP = x.LPRUP;
+    return *this;
+  }
+
+  /**
+   * Destructor.
+   */
+  ~HEPRUP() {}
+  //@}
+
+public:
+
+  /**
+   * Set the NPRUP variable, corresponding to the number of
+   * sub-processes, to \a nrup, and resize all relevant vectors
+   * accordingly.
+   */
+  void resize(int nrup) {
+    NPRUP = nrup;
+    resize();
+  }
+
+  /**
+   * Assuming the NPRUP variable, corresponding to the number of
+   * sub-processes, is correctly set, resize the relevant vectors
+   * accordingly.
+   */
+  void resize() {
+    XSECUP.resize(NPRUP);
+    XERRUP.resize(NPRUP);
+    XMAXUP.resize(NPRUP);
+    LPRUP.resize(NPRUP);
+  }
+
+public:
+
+  /**
+   * PDG id's of beam particles. (first/second is in +/-z direction).
+   */
+  std::pair<long,long> IDBMUP;
+
+  /**
+   * Energy of beam particles given in GeV.
+   */
+  std::pair<double,double> EBMUP;
+
+  /**
+   * The author group for the PDF used for the beams according to the
+   * PDFLib specification.
+   */
+  std::pair<int,int> PDFGUP;
+
+  /**
+   * The id number the PDF used for the beams according to the
+   * PDFLib specification.
+   */
+  std::pair<int,int> PDFSUP;
+
+  /**
+   * Master switch indicating how the ME generator envisages the
+   * events weights should be interpreted according to the Les Houches
+   * accord.
+   */
+  int IDWTUP;
+
+  /**
+   * The number of different subprocesses in this file.
+   */
+  int NPRUP;
+
+  /**
+   * The cross sections for the different subprocesses in pb.
+   */
+  std::vector<double> XSECUP;
+
+  /**
+   * The statistical error in the cross sections for the different
+   * subprocesses in pb.
+   */
+  std::vector<double> XERRUP;
+
+  /**
+   * The maximum event weights (in HEPEUP::XWGTUP) for different
+   * subprocesses.
+   */
+  std::vector<double> XMAXUP;
+
+  /**
+   * The subprocess code for the different subprocesses.
+   */
+  std::vector<int> LPRUP;
+
+};
+
+
+/**
+ * The HEPEUP class is a simple container corresponding to the Les Houches accord
+ * (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>)
+ * common block with the same name. The members are named in the same
+ * way as in the common block. However, fortran arrays are represented
+ * by vectors, except for the arrays of length two which are
+ * represented by pair objects.
+ */
+class HEPEUP {
+
+public:
+
+  /** @name Standard constructors and destructors. */
+  //@{
+  /**
+   * Default constructor.
+   */
+  HEPEUP()
+    : NUP(0), IDPRUP(0), XWGTUP(0.0), XPDWUP(0.0, 0.0),
+      SCALUP(0.0), AQEDUP(0.0), AQCDUP(0.0) {}
+
+  /**
+   * Copy-constructor.
+   */
+  HEPEUP(const HEPEUP & x)
+    : NUP(x.NUP), IDPRUP(x.IDPRUP), XWGTUP(x.XWGTUP), XPDWUP(x.XPDWUP),
+      SCALUP(x.SCALUP), AQEDUP(x.AQEDUP), AQCDUP(x.AQCDUP), IDUP(x.IDUP),
+      ISTUP(x.ISTUP), MOTHUP(x.MOTHUP), ICOLUP(x.ICOLUP),
+      PUP(x.PUP), VTIMUP(x.VTIMUP), SPINUP(x.SPINUP) {}
+  
+  /**
+   * Assignment operator.
+   */
+  HEPEUP & operator=(const HEPEUP & x) {
+    NUP = x.NUP;
+    IDPRUP = x.IDPRUP;
+    XWGTUP = x.XWGTUP;
+    XPDWUP = x.XPDWUP;
+    SCALUP = x.SCALUP;
+    AQEDUP = x.AQEDUP;
+    AQCDUP = x.AQCDUP;
+    IDUP = x.IDUP;
+    ISTUP = x.ISTUP;
+    MOTHUP = x.MOTHUP;
+    ICOLUP = x.ICOLUP;
+    PUP = x.PUP;
+    VTIMUP = x.VTIMUP;
+    SPINUP = x.SPINUP;
+    return *this;
+  }
+
+
+  /**
+   * Destructor.
+   */
+  ~HEPEUP() {};
+  //@}
+
+public:
+
+  /**
+   * Set the NUP variable, corresponding to the number of particles in
+   * the current event, to \a nup, and resize all relevant vectors
+   * accordingly.
+   */
+  void resize(int nup) {
+    NUP = nup;
+    resize();
+  }
+
+  /**
+   * Assuming the NUP variable, corresponding to the number of
+   * particles in the current event, is correctly set, resize the
+   * relevant vectors accordingly.
+   */
+  void resize() {
+    IDUP.resize(NUP);
+    ISTUP.resize(NUP);
+    MOTHUP.resize(NUP);
+    ICOLUP.resize(NUP);
+    PUP.resize(NUP, std::vector<double>(5));
+    VTIMUP.resize(NUP);
+    SPINUP.resize(NUP);
+  }
+
+public:
+
+  /**
+   * The number of particle entries in the current event.
+   */
+  int NUP;
+
+  /**
+   * The subprocess code for this event (as given in LPRUP).
+   */
+  int IDPRUP;
+
+  /**
+   * The weight for this event.
+   */
+  double XWGTUP;
+
+  /**
+   * The PDF weights for the two incoming partons. Note that this
+   * variable is not present in the current LesHouches accord
+   * (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>),
+   * hopefully it will be present in a future accord.
+   */
+  std::pair<double,double> XPDWUP;
+
+  /**
+   * The scale in GeV used in the calculation of the PDF's in this
+   * event.
+   */
+  double SCALUP;
+
+  /**
+   * The value of the QED coupling used in this event.
+   */
+  double AQEDUP;
+
+  /**
+   * The value of the QCD coupling used in this event.
+   */
+  double AQCDUP;
+
+  /**
+   * The PDG id's for the particle entries in this event.
+   */
+  std::vector<long> IDUP;
+
+  /**
+   * The status codes for the particle entries in this event.
+   */
+  std::vector<int> ISTUP;
+
+  /**
+   * Indices for the first and last mother for the particle entries in
+   * this event.
+   */
+  std::vector< std::pair<int,int> > MOTHUP;
+
+  /**
+   * The colour-line indices (first(second) is (anti)colour) for the
+   * particle entries in this event.
+   */
+  std::vector< std::pair<int,int> > ICOLUP;
+
+  /**
+   * Lab frame momentum (Px, Py, Pz, E and M in GeV) for the particle
+   * entries in this event.
+   */
+  std::vector< std::vector<double> > PUP;
+
+  /**
+   * Invariant lifetime (c*tau, distance from production to decay in
+   * mm) for the particle entries in this event.
+   */
+  std::vector<double> VTIMUP;
+
+  /**
+   * Spin info for the particle entries in this event given as the
+   * cosine of the angle between the spin vector of a particle and the
+   * 3-momentum of the decaying particle, specified in the lab frame.
+   */
+  std::vector<double> SPINUP;
+
+};
+
+/**
+ * The Reader class is initialized with a stream from which to read a
+ * version 1.0 Les Houches Accord event file. In the constructor of
+ * the Reader object the optional header information is read and then
+ * the mandatory init is read. After this the whole header block
+ * including the enclosing lines with tags are available in the public
+ * headerBlock member variable. Also the information from the init
+ * block is available in the heprup member variable and any additional
+ * comment lines are available in initComments. After each successful
+ * call to the readEvent() function the standard Les Houches Accord
+ * information about the event is available in the hepeup member
+ * variable and any additional comments in the eventComments
+ * variable. A typical reading sequence would look as follows:
+ *
+ *
+ */
+class Reader {
+
+public:
+
+  /**
+   * Initialize the Reader with a stream from which to read an event
+   * file. After the constructor is called the whole header block
+   * including the enclosing lines with tags are available in the
+   * public headerBlock member variable. Also the information from the
+   * init block is available in the heprup member variable and any
+   * additional comment lines are available in initComments.
+   *
+   * @param is the stream to read from.
+   */
+  Reader(std::istream & is)
+    : file(is) {
+    init();
+  }
+
+  /**
+   * Initialize the Reader with a filename from which to read an event
+   * file. After the constructor is called the whole header block
+   * including the enclosing lines with tags are available in the
+   * public headerBlock member variable. Also the information from the
+   * init block is available in the heprup member variable and any
+   * additional comment lines are available in initComments.
+   *
+   * @param filename the name of the file to read from.
+   */
+  Reader(std::string filename)
+    : intstream(filename.c_str()), file(intstream) {
+    init();
+  }
+
+private:
+
+  /**
+   * Used internally in the constructors to read header and init
+   * blocks.
+   */
+  void init() {
+
+    bool readingHeader = false;
+    bool readingInit = false;
+
+    // Make sure we are reading a LHEF file:
+    getline();
+    if ( currentLine.find("<LesHouchesEvents" ) == std::string::npos )
+      throw std::runtime_error
+	("Tried to read a file which does not start with the "
+	 "LesHouchesEvents tag.");
+    if ( currentLine.find("version=\"1.0\"" ) == std::string::npos )
+      throw std::runtime_error
+	("Tried to read a LesHouchesEvents file which is not version 1.0.");
+
+    // Loop over all lines until we hit the </init> tag.
+    while ( getline() && currentLine.find("</init>") == std::string::npos ) {
+      if ( currentLine.find("<header") != std::string::npos ) {
+	// We have hit the header block, so we should dump this all
+	// following lines to headerBlock until we hit the end of it.
+	readingHeader = true;
+	headerBlock = currentLine + "\n";
+      }
+      else if ( currentLine.find("<init") != std::string::npos ) {
+	// We have hit the init block, so we should expect to find the
+	// standard information in the following.
+	readingInit = true;
+
+	// The first line tells us how many lines to read next.
+	getline();
+	std::istringstream iss(currentLine);
+	if ( !( iss >> heprup.IDBMUP.first >> heprup.IDBMUP.second
+		    >> heprup.EBMUP.first >> heprup.EBMUP.second
+	            >> heprup.PDFGUP.first >> heprup.PDFGUP.second
+	            >> heprup.PDFSUP.first >> heprup.PDFSUP.second
+		    >> heprup.IDWTUP >> heprup.NPRUP ) ) {
+	  heprup.NPRUP = -42;
+	  return;
+	}
+	heprup.resize();
+
+	for ( int i = 0; i < heprup.NPRUP; ++i ) {
+	  getline();
+	  std::istringstream iss(currentLine);
+	  if ( !( iss >> heprup.XSECUP[i] >> heprup.XERRUP[i]
+	              >> heprup.XMAXUP[i] >> heprup.LPRUP[i] ) ) {
+	    heprup.NPRUP = -42;
+	    return;
+	  }
+	}
+      }
+      else if ( currentLine.find("</header>") != std::string::npos ) {
+	// The end of the header block. Dump this line as well to the
+	// headerBlock and we're done.
+	readingHeader = false;
+	headerBlock += currentLine + "\n";
+      }
+      else if ( readingHeader ) {
+	// We are in the process of reading the header block. Dump the
+	// line to haderBlock.
+	headerBlock += currentLine + "\n";
+      }
+      else if ( readingInit ) {
+	// Here we found a comment line. Dump it to initComments.
+	initComments += currentLine + "\n";
+      }
+      else {
+	// We found some other stuff outside the standard tags.
+	outsideBlock += currentLine + "\n";
+      }
+    }
+    if ( !file ) heprup.NPRUP = -42;
+  }
+
+public:
+
+  int getNumberOfEvents()
+  {
+    int counter = 0;
+    int position = file.tellg();
+    file.seekg(0, std::ios::beg);
+
+    file.clear();
+
+    while(getline())
+    {
+      if(currentLine.find("<event") != std::string::npos) ++counter;
+    }
+
+    file.clear();
+
+    file.seekg(position, std::ios::beg);
+
+    return counter;
+  }
+
+  /**
+   * Read an event from the file and store it in the hepeup
+   * object. Optional comment lines are stored i the eventComments
+   * member variable.
+   * @return true if the read sas successful.
+   */
+  bool readEvent() {
+
+    // Check if the initialization was successful. Otherwise we will
+    // not read any events.
+    if ( heprup.NPRUP < 0 ) return false;
+    eventComments = "";
+    outsideBlock = "";
+    hepeup.NUP = 0;
+
+    // Keep reading lines until we hit the next event or the end of
+    // the event block. Save any inbetween lines. Exit if we didn't
+    // find an event.
+    while ( getline() && currentLine.find("<event") == std::string::npos )
+      outsideBlock += currentLine + "\n";
+    if ( !getline()  ) return false;
+    
+    // We found an event. The first line determines how many
+    // subsequent particle lines we have.
+    std::istringstream iss(currentLine);
+    if ( !( iss >> hepeup.NUP >> hepeup.IDPRUP >> hepeup.XWGTUP
+	        >> hepeup.SCALUP >> hepeup.AQEDUP >> hepeup.AQCDUP ) )
+      return false;
+    hepeup.resize();
+
+    // Read all particle lines.
+    for ( int i = 0; i < hepeup.NUP; ++i ) {
+      if ( !getline() ) return false;
+      std::istringstream iss(currentLine);
+      if ( !( iss >> hepeup.IDUP[i] >> hepeup.ISTUP[i]
+	          >> hepeup.MOTHUP[i].first >> hepeup.MOTHUP[i].second
+         	  >> hepeup.ICOLUP[i].first >> hepeup.ICOLUP[i].second
+	          >> hepeup.PUP[i][0] >> hepeup.PUP[i][1] >> hepeup.PUP[i][2]
+	          >> hepeup.PUP[i][3] >> hepeup.PUP[i][4]
+        	  >> hepeup.VTIMUP[i] >> hepeup.SPINUP[i] ) )
+	return false;
+    }
+
+    // Now read any additional comments.
+    while ( getline() && currentLine.find("</event>") == std::string::npos )
+      eventComments += currentLine + "\n";
+
+    if ( !file ) return false;
+    return true;
+
+  }
+
+protected:
+
+  /**
+   * Used internally to read a single line from the stream.
+   */
+  bool getline() {
+    return ( std::getline(file, currentLine) );
+  }
+
+protected:
+
+  /**
+   * A local stream which is unused if a stream is supplied from the
+   * outside.
+   */
+  std::ifstream intstream;
+
+  /**
+   * The stream we are reading from. This may be a reference to an
+   * external stream or the internal intstream.
+   */
+  std::istream & file;
+
+  /**
+   * The last line read in from the stream in getline().
+   */
+  std::string currentLine;
+
+public:
+
+  /**
+   * All lines (since the last readEvent()) outside the header, init
+   * and event tags.
+   */
+  std::string outsideBlock;
+
+  /**
+   * All lines from the header block.
+   */
+  std::string headerBlock;
+
+  /**
+   * The standard init information.
+   */
+  HEPRUP heprup;
+
+  /**
+   * Additional comments found in the init block.
+   */
+  std::string initComments;
+
+  /**
+   * The standard information about the last read event.
+   */
+  HEPEUP hepeup;
+
+  /**
+   * Additional comments found with the last read event.
+   */
+  std::string eventComments;
+
+private:
+
+  /**
+   * The default constructor should never be used.
+   */
+  Reader();
+
+  /**
+   * The copy constructor should never be used.
+   */
+  Reader(const Reader &);
+
+  /**
+   * The Reader cannot be assigned to.
+   */
+  Reader & operator=(const Reader &);
+
+};
+
+/**
+ * The Writer class is initialized with a stream to which to write a
+ * version 1.0 Les Houches Accord event file. In the constructor of
+ * the Writer object the main XML tag is written out, with the
+ * corresponding end tag is written in the destructor. After a Writer
+ * object has been created, it is possible to assign standard init
+ * information in the heprup member variable. In addition any XML
+ * formatted information can be added to the headerBlock member
+ * variable (directly or via the addHeader() function). Further
+ * comment line (beginning with a <code>#</code> character) can be
+ * added to the initComments variable (directly or with the
+ * addInitComment() function). After this information is set, it
+ * should be written out to the file with the init() function.
+ *
+ * Before each event is written out with the writeEvent() function,
+ * the standard event information can then be assigned to the hepeup
+ * variable and optional comment lines (beginning with a
+ * <code>#</code> character) may be given to the eventComments
+ * variable (directly or with the addEventComment() function).
+ *
+ */
+class Writer {
+
+public:
+
+  /**
+   * Create a Writer object giving a stream to write to.
+   * @param os the stream where the event file is written.
+   */
+  Writer(std::ostream & os)
+    : file(os) {
+    // Write out the standard XML tag for the event file.
+    file << "<LesHouchesEvents version=\"1.0\">\n";
+  }
+
+  /**
+   * Create a Writer object giving a filename to write to.
+   * @param filename the name of the event file to be written.
+   */
+  Writer(std::string filename)
+    : intstream(filename.c_str()), file(intstream) {
+    // Write out the standard XML tag for the event file.
+    file << "LesHouchesEvents version=\"1.0\">\n";
+  }
+
+  /**
+   * The destructor writes out the final XML end-tag.
+   */
+  ~Writer() {
+    file << "</LesHouchesEvents>" << std::endl;
+  }
+
+  /**
+   * Add header lines consisting of XML code with this stream.
+   */
+  std::ostream & headerBlock() {
+    return headerStream;
+  }
+
+  /**
+   * Add comment lines to the init block with this stream.
+   */
+  std::ostream & initComments() {
+    return initStream;
+  }
+
+  /**
+   * Add comment lines to the next event to be written out with this stream.
+   */
+  std::ostream & eventComments() {
+    return eventStream;
+  }
+
+  /**
+   * Write out an optional header block followed by the standard init
+   * block information together with any comment lines.
+   */
+  void init() {
+
+    file << std::setprecision(8);
+
+    using std::setw;
+
+    std::string headerBlock = headerStream.str();
+    if ( headerBlock.length() ) {
+      if ( headerBlock.find("<header>") == std::string::npos )
+	file << "<header>\n";
+      if ( headerBlock[headerBlock.length() - 1] != '\n' )
+	headerBlock += '\n';
+      file << headerBlock;
+      if ( headerBlock.find("</header>") == std::string::npos )
+	file << "</header>\n";
+    }
+    file << "<init>\n"
+	 << " " << setw(8) << heprup.IDBMUP.first
+	 << " " << setw(8) << heprup.IDBMUP.second
+	 << " " << setw(14) << heprup.EBMUP.first
+	 << " " << setw(14) << heprup.EBMUP.second
+	 << " " << setw(4) << heprup.PDFGUP.first
+	 << " " << setw(4) << heprup.PDFGUP.second
+	 << " " << setw(4) << heprup.PDFSUP.first
+	 << " " << setw(4) << heprup.PDFSUP.second
+	 << " " << setw(4) << heprup.IDWTUP
+	 << " " << setw(4) << heprup.NPRUP << std::endl;
+    heprup.resize();
+    for ( int i = 0; i < heprup.NPRUP; ++i )
+      file << " " << setw(14) << heprup.XSECUP[i]
+	   << " " << setw(14) << heprup.XERRUP[i]
+	   << " " << setw(14) << heprup.XMAXUP[i]
+	   << " " << setw(6) << heprup.LPRUP[i] << std::endl;
+    file << hashline(initStream.str()) << "</init>" << std::endl;
+    eventStream.str("");
+  }
+
+  /**
+   * Write out the event stored in hepeup, followed by optional
+   * comment lines.
+   */
+  bool writeEvent() {
+
+    using std::setw;
+
+    file << "<event>\n";
+    file << " " << setw(4) << hepeup.NUP
+	 << " " << setw(6) << hepeup.IDPRUP
+	 << " " << setw(14) << hepeup.XWGTUP
+	 << " " << setw(14) << hepeup.SCALUP
+	 << " " << setw(14) << hepeup.AQEDUP
+	 << " " << setw(14) << hepeup.AQCDUP << "\n";
+    hepeup.resize();
+
+    for ( int i = 0; i < hepeup.NUP; ++i )
+      file << " " << setw(8) << hepeup.IDUP[i]
+	   << " " << setw(2) << hepeup.ISTUP[i]
+	   << " " << setw(4) << hepeup.MOTHUP[i].first
+	   << " " << setw(4) << hepeup.MOTHUP[i].second
+	   << " " << setw(4) << hepeup.ICOLUP[i].first
+	   << " " << setw(4) << hepeup.ICOLUP[i].second
+	   << " " << setw(14) << hepeup.PUP[i][0]
+	   << " " << setw(14) << hepeup.PUP[i][1]
+	   << " " << setw(14) << hepeup.PUP[i][2]
+	   << " " << setw(14) << hepeup.PUP[i][3]
+	   << " " << setw(14) << hepeup.PUP[i][4]
+	   << " " << setw(1) << hepeup.VTIMUP[i]
+	   << " " << setw(1) << hepeup.SPINUP[i] << std::endl;
+
+    file << hashline(eventStream.str()) << "</event>\n";
+
+    eventStream.str("");
+
+    if ( !file ) return false;
+
+    return true;
+
+  }
+
+protected:
+
+  /**
+   * Make sure that each line in the string \a s starts with a
+   * #-character and that the string ends with a new-line.
+   */
+  std::string hashline(std::string s) {
+    std::string ret;
+    std::istringstream is(s);
+    std::string ss;
+    while ( getline(is, ss) ) {
+      if ( ss.find('#') == std::string::npos ||
+	   ss.find('#') != ss.find_first_not_of(" \t") ) ss = "# " + ss;
+      ret += ss + '\n';
+    }
+    return ret;
+  }
+
+protected:
+
+  /**
+   * A local stream which is unused if a stream is supplied from the
+   * outside.
+   */
+  std::ofstream intstream;
+
+  /**
+   * The stream we are writing to. This may be a reference to an
+   * external stream or the internal intstream.
+   */
+  std::ostream & file;
+
+public:
+
+  /**
+   * Stream to add all lines in the header block.
+   */
+  std::ostringstream headerStream;
+
+  /**
+   * The standard init information.
+   */
+  HEPRUP heprup;
+
+  /**
+   * Stream to add additional comments to be put in the init block.
+   */
+  std::ostringstream initStream;
+
+  /**
+   * The standard information about the event we will write next.
+   */
+  HEPEUP hepeup;
+
+  /**
+   * Stream to add additional comments to be written together the next event.
+   */
+  std::ostringstream eventStream;
+
+private:
+
+  /**
+   * The default constructor should never be used.
+   */
+  Writer();
+
+  /**
+   * The copy constructor should never be used.
+   */
+  Writer(const Writer &);
+
+  /**
+   * The Writer cannot be assigned to.
+   */
+  Writer & operator=(const Writer &);
+
+};
+
+}
+
+/** \example LHEFReadEx.cc An example function which reads from a Les
+    Huches Event File: */
+/** \example LHEFWriteEx.cc An example function which writes out a Les
+    Huches Event File: */
+/** \example LHEFCat.cc This is a main function which simply reads a
+    Les Houches Event File from the standard input and writes it again
+    to the standard output. 
+    This file can be downloaded from
+    <A HREF="http://www.thep.lu.se/~leif/LHEF/LHEFCat.cc">here</A>. 
+    There is also a sample
+    <A HREF="http://www.thep.lu.se/~leif/LHEF/ttbar.lhef">event file</A>
+    to try it on.
+*/
+
+/**\mainpage Les Houches Event File
+
+Why isn't any doxygen output generated by this text?
+
+Here are some example classes for reading and writing Les Houches
+Event Files according to the
+<A HREF="http://www.thep.lu.se/~torbjorn/lhef/lhafile2.pdf">proposal</A>
+by Torbj&ouml;rn Sj&ouml;strand discussed at the
+<A HREF="http://mc4lhc06.web.cern.ch/mc4lhc06/">MC4LHC</A>
+workshop at CERN 2006.
+
+In total there are four classes which are all available in a single
+header file called
+<A HREF="http://www.thep.lu.se/~leif/LHEF/LHEF.h">LHEF.h</A>.
+
+The two classes LHEF::HEPRUP and LHEF::HEPEUP are simple container
+classes which contain the same information as the Les Houches standard
+Fortran common blocks with the same names. The other two classes are
+called LHEF::Reader and LHEF::Writer and are used to read and write
+Les Houches Event Files
+
+Here are a few <A HREF="examples.html">examples</A> of how to use the
+classes:
+
+\namespace LHEF The LHEF namespace contains some example classes for reading and writing Les Houches
+Event Files according to the
+<A HREF="http://www.thep.lu.se/~torbjorn/lhef/lhafile2.pdf">proposal</A>
+by Torbj&ouml;rn Sj&ouml;strand discussed at the
+<A HREF="http://mc4lhc06.web.cern.ch/mc4lhc06/">MC4LHC</A>
+workshop at CERN 2006.
+
+
+
+ */
+
+
+#endif /* THEPEG_LHEF_H */
Index: /trunk/Utilities/ExRootAnalysis/interface/TBaseTree.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/TBaseTree.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/TBaseTree.h	(revision 3)
@@ -0,0 +1,47 @@
+#ifndef TBaseTree_h
+#define TBaseTree_h
+
+#include "Utilities/ExRootAnalysis/interface/TSimpleBranch.h"
+
+#include "TROOT.h"
+
+#include <set>
+
+class TFile;
+class TTree;
+
+class TBaseTree
+{
+private:
+
+  static const Int_t maxElecEntries = 30;
+  static const Int_t maxGenEntries = 30;
+  static const Int_t maxJetEntries = 30;
+  
+public:
+  
+  TBaseTree(const TString &name);
+  ~TBaseTree();
+
+  template<typename T>
+  TSimpleBranch<T> *NewBranch(const TString &name, Int_t maxsize)
+  {
+    TSimpleBranch<T> *branch = new TSimpleBranch<T>(name, maxsize, fNewTree);
+    fBranches.insert(branch);
+    return branch;
+  }
+
+  void Clear();
+  void Fill();
+  void Write();
+
+private:
+
+  TFile *fNewFile;
+  TTree *fNewTree;
+
+  std::set<TBaseBranch*> fBranches;
+};
+
+#endif /* TBaseTree */
+
Index: /trunk/Utilities/ExRootAnalysis/interface/TSimpleArray.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/TSimpleArray.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/TSimpleArray.h	(revision 3)
@@ -0,0 +1,233 @@
+#ifndef TSimpleArray_h
+#define TSimpleArray_h
+
+#include "TObjArray.h"
+#include "TRefArray.h"
+
+#include <map>
+
+class TCompare;
+
+class TBaseArray
+{
+  public:
+  TBaseArray(Int_t size = 100) :
+    fIsOwner(kTRUE), fIsRefArray(kFALSE), fArray(0), fIter(0)
+  {
+    fArray = new TObjArray(size);
+    fIter = fArray->MakeIterator();
+  }
+  
+  TBaseArray(TObjArray *array) :
+    fIsOwner(kFALSE), fIsRefArray(kFALSE), fArray(array), fIter(0)
+  {
+    fIter = fArray->MakeIterator();
+  }
+
+  TBaseArray(TRefArray &array) :
+    fIsOwner(kFALSE), fIsRefArray(kTRUE), fArray(&array), fIter(0)
+  {
+    fIter = fArray->MakeIterator();
+  }
+
+  virtual ~TBaseArray()
+  {
+    delete fIter;
+    if(fIsOwner) delete fArray;
+  }
+
+  Int_t GetEntries() const
+  {
+    if(fIsRefArray)
+    {
+      return static_cast<TRefArray*>(fArray)->GetEntriesFast();
+    }
+    else
+    {
+      return static_cast<TObjArray*>(fArray)->GetEntriesFast();
+    }
+  }    
+
+  void Clear()
+  {
+    fArray->Clear();
+    Reset();
+    ClearFilter();
+  }
+
+  void Reset() { fIter->Reset(); }
+
+  virtual void ClearFilter(const void *filter = 0) = 0;
+
+private:
+
+  Bool_t fIsOwner;
+
+protected:
+
+  Bool_t fIsRefArray;
+  TSeqCollection *fArray;
+  TIterator *fIter;
+};
+
+//------------------------------------------------------------------------------
+
+template<typename T>
+class TSimpleArray: public TBaseArray
+{
+public:
+
+  class FilterExeption{};
+
+  TSimpleArray(Int_t size = 100) :
+    TBaseArray(size), fMap() {}
+
+  TSimpleArray(TObjArray *array) :
+    TBaseArray(array), fMap() {}
+
+  TSimpleArray(TRefArray &array) :
+    TBaseArray(array), fMap() {}
+  
+  ~TSimpleArray()
+  {
+    TFilterMapConstIter it_map;
+    TCategoryMapConstIter it_submap;
+    for(it_map = fMap.begin(); it_map != fMap.end(); ++it_map)
+    {
+      for(it_submap = it_map->second.second.begin();
+          it_submap != it_map->second.second.end(); ++it_submap)
+      {
+        delete (it_submap->second);
+      }
+    }
+  }
+
+  void ClearFilter(const void *filter = 0)
+  {
+    TFilterMapIter it_map;
+    TCategoryMapIter it_submap;
+    if(filter)
+    {
+      it_map = fMap.find(filter);
+      if(it_map != fMap.end())
+      {
+        it_map->second.first = kTRUE;
+        for(it_submap = it_map->second.second.begin();
+            it_submap != it_map->second.second.end(); ++it_submap)
+        {
+          it_submap->second->Clear();
+        }
+      }
+    }
+    else
+    {
+      for(it_map = fMap.begin(); it_map != fMap.end(); ++it_map)
+      {
+        it_map->second.first = kTRUE;
+        for(it_submap = it_map->second.second.begin();
+            it_submap != it_map->second.second.end(); ++it_submap)
+        {
+          it_submap->second->Clear();
+        }
+      }
+    }
+  }
+  
+  void Add(T *obj) { fArray->Add(obj); }
+
+  T *At(Int_t i) const
+  {
+    if(fIsRefArray)
+    {
+      return static_cast<T*>((*static_cast<TRefArray*>(fArray))[i]); 
+    }
+    else
+    {
+      return static_cast<T*>((*static_cast<TObjArray*>(fArray))[i]); 
+    }
+  }
+  T *operator[](Int_t i) const { return At(i); }
+
+  void Sort(TCompare *comp = 0)
+  {
+    TCompare *temp = T::fgCompare;
+    if(comp)
+    {
+      T::fgCompare = comp;
+    }
+    if(fIsRefArray)
+    {
+      static_cast<TRefArray*>(fArray)->Sort();
+    }
+    else
+    {
+      static_cast<TObjArray*>(fArray)->Sort();
+    }
+    if(comp)
+    {
+      T::fgCompare = temp;
+    }
+  }
+
+  template <typename F>
+  TSimpleArray<T> *GetSubArray(const F *filter, Int_t category = 1)
+  {
+    T *element;
+    Int_t result;
+    TCategoryMapIter it_submap;
+    std::pair<TCategoryMapIter, bool> pair_submap;
+    std::pair<TFilterMapIter, bool> pair_map;
+
+    TFilterMapIter it_map = fMap.find(filter);
+    if(it_map == fMap.end())
+    {
+      pair_map = fMap.insert(make_pair(filter, make_pair(kTRUE, TCategoryMap())));
+      if(!pair_map.second) throw FilterExeption();
+
+      it_map = pair_map.first;
+    }
+
+    if(it_map->second.first)
+    {
+      it_map->second.first = kFALSE;
+      Reset();
+      while(element = Next())
+      {
+        result = (*filter)(element);
+        if(result < 0) continue;
+        it_submap = it_map->second.second.find(result);
+        if(it_submap == it_map->second.second.end())
+        {
+          pair_submap = it_map->second.second.insert(make_pair(result,
+                                                               new TSimpleArray<T>(fArray->GetSize())));
+          if(!pair_submap.second) throw FilterExeption();
+
+          pair_submap.first->second->Add(element);
+        }
+        else
+        {
+          it_submap->second->Add(element);
+        }
+      }
+    }
+
+    it_submap = it_map->second.second.find(category);
+    return (it_submap != it_map->second.second.end()) ? it_submap->second : 0;
+  }
+
+  T *Next() { return static_cast<T*>(fIter->Next()); }
+
+private:
+  typedef std::map<Int_t, TSimpleArray<T>*> TCategoryMap;
+  typedef std::map< const void*, std::pair<Bool_t, TCategoryMap> > TFilterMap;
+
+  typedef typename TFilterMap::iterator TFilterMapIter;
+  typedef typename TCategoryMap::iterator TCategoryMapIter;
+  typedef typename TFilterMap::const_iterator TFilterMapConstIter;
+  typedef typename TCategoryMap::const_iterator TCategoryMapConstIter;
+
+  TFilterMap fMap;
+};
+
+#endif /* TSimpleArray */
+
Index: /trunk/Utilities/ExRootAnalysis/interface/TSimpleBranch.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/TSimpleBranch.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/TSimpleBranch.h	(revision 3)
@@ -0,0 +1,64 @@
+#ifndef TSimpleBranch_h
+#define TSimpleBranch_h
+
+#include "TTree.h"
+#include "TClonesArray.h"
+
+class TBaseBranch
+{
+public:
+
+  class OverFlow{};
+
+  TBaseBranch() : fSize(0), fMaxSize(0), fData(0) {}
+
+  ~TBaseBranch() { if(fData) delete fData; }
+
+  void Clear()
+  {
+    fSize = 0;
+    if(fData) fData->Clear();
+  }
+
+protected:
+
+  Int_t fSize, fMaxSize;
+  TClonesArray *fData;
+};
+
+//------------------------------------------------------------------------------
+
+template<typename T>
+class TSimpleBranch: public TBaseBranch
+{
+public:
+
+  TSimpleBranch(const TString &name, Int_t maxsize, TTree *tree)
+  {
+    fMaxSize = maxsize;
+
+    if(fMaxSize > 1)
+    {
+      tree->Branch(name + "_size", &fSize, name + "_size/I");
+    }
+    else
+    {
+      fMaxSize = 1;
+    }
+
+    T::Class()->IgnoreTObjectStreamer();
+    fData = new TClonesArray(T::Class(), maxsize);
+    fData->ExpandCreateFast(maxsize);
+
+    tree->Branch(name, &fData, 64000, 2);
+  }
+
+  T *NewEntry()
+  {
+    if(fSize >= fMaxSize) throw OverFlow();
+    return fData ? static_cast<T*>(fData->AddrAt(fSize++)) : 0;
+  }
+};
+
+#endif /* TSimpleBranch */
+
Index: /trunk/Utilities/ExRootAnalysis/interface/TdrStyle.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/interface/TdrStyle.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/interface/TdrStyle.h	(revision 3)
@@ -0,0 +1,114 @@
+#ifndef __TDRSTYLE__
+#define __TDRSTYLE__
+
+#include "TStyle.h"
+
+void setTDRStyle() {
+  TStyle *tdrStyle = new TStyle("tdrStyle","Style for P-TDR");
+
+  // For the canvas:
+  tdrStyle->SetCanvasBorderMode(0);
+  tdrStyle->SetCanvasColor(kWhite);
+  tdrStyle->SetCanvasDefH(600); //Height of canvas
+  tdrStyle->SetCanvasDefW(600); //Width of canvas
+  tdrStyle->SetCanvasDefX(0);   //POsition on screen
+  tdrStyle->SetCanvasDefY(0);
+
+  // For the Pad:
+  tdrStyle->SetPadBorderMode(0);
+  tdrStyle->SetPadColor(kWhite);
+  tdrStyle->SetPadGridX(false);
+  tdrStyle->SetPadGridY(false);
+  tdrStyle->SetGridColor(0);
+  tdrStyle->SetGridStyle(3);
+  tdrStyle->SetGridWidth(1);
+
+  // For the frame:
+  tdrStyle->SetFrameBorderMode(0);
+  tdrStyle->SetFrameBorderSize(1);
+  tdrStyle->SetFrameFillColor(0);
+  tdrStyle->SetFrameFillStyle(0);
+  tdrStyle->SetFrameLineColor(1);
+  tdrStyle->SetFrameLineStyle(1);
+  tdrStyle->SetFrameLineWidth(1);
+
+  // For the histo:
+  tdrStyle->SetHistLineColor(1);
+  tdrStyle->SetHistLineStyle(0);
+  tdrStyle->SetHistLineWidth(1);
+
+  tdrStyle->SetEndErrorSize(2);
+  tdrStyle->SetErrorX(0.);
+  
+  tdrStyle->SetMarkerStyle(20);
+
+  //For the fit/function:
+  tdrStyle->SetOptFit(1);
+  tdrStyle->SetFitFormat("5.4g");
+  tdrStyle->SetFuncColor(2);
+  tdrStyle->SetFuncStyle(1);
+  tdrStyle->SetFuncWidth(1);
+
+  //For the date:
+  tdrStyle->SetOptDate(0);
+ 
+  // For the statistics box:
+  tdrStyle->SetOptFile(0);
+  tdrStyle->SetOptStat(0); // To display the mean and RMS:   SetOptStat("mr");
+  tdrStyle->SetStatColor(kWhite);
+  tdrStyle->SetStatFont(42);
+  tdrStyle->SetStatFontSize(0.025);
+  tdrStyle->SetStatTextColor(1);
+  tdrStyle->SetStatFormat("6.4g");
+  tdrStyle->SetStatBorderSize(1);
+  tdrStyle->SetStatH(0.1);
+  tdrStyle->SetStatW(0.15);
+
+  // Margins:
+  tdrStyle->SetPadTopMargin(0.05);
+  tdrStyle->SetPadBottomMargin(0.13);
+  tdrStyle->SetPadLeftMargin(0.13);
+  tdrStyle->SetPadRightMargin(0.05);
+
+  // For the Global title:
+
+  tdrStyle->SetTitleFont(42);
+  tdrStyle->SetTitleColor(1);
+  tdrStyle->SetTitleTextColor(1);
+  tdrStyle->SetTitleFillColor(10);
+  tdrStyle->SetTitleFontSize(0.04);
+ 
+  // For the axis titles:
+
+  tdrStyle->SetTitleColor(1, "XYZ");
+  tdrStyle->SetTitleFont(42, "XYZ");
+  tdrStyle->SetTitleSize(0.05, "XYZ");
+  tdrStyle->SetTitleXOffset(0.9);
+  tdrStyle->SetTitleYOffset(1.05);
+
+  // For the axis labels:
+
+  tdrStyle->SetLabelColor(1, "XYZ");
+  tdrStyle->SetLabelFont(42, "XYZ");
+  tdrStyle->SetLabelOffset(0.007, "XYZ");
+  tdrStyle->SetLabelSize(0.04, "XYZ");
+
+  // For the axis:
+
+  tdrStyle->SetAxisColor(1, "XYZ");
+  tdrStyle->SetStripDecimals(kTRUE);
+  tdrStyle->SetTickLength(0.03, "XYZ");
+  tdrStyle->SetNdivisions(510, "XYZ");
+  tdrStyle->SetPadTickX(1);  // To get tick marks on the opposite side of the frame
+  tdrStyle->SetPadTickY(1);
+
+  // Change for log plots:
+  tdrStyle->SetOptLogx(0);
+  tdrStyle->SetOptLogy(0);
+  tdrStyle->SetOptLogz(0);
+
+  tdrStyle->cd();
+
+}
+
+#endif
Index: /trunk/Utilities/ExRootAnalysis/src/BlockClasses.cc
===================================================================
--- /trunk/Utilities/ExRootAnalysis/src/BlockClasses.cc	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/src/BlockClasses.cc	(revision 3)
@@ -0,0 +1,48 @@
+/** \class BlockClasses
+ *
+ *  Initialization of static fgCompare functions. At the moment a number of 
+ *  functions TCompare*** are implemented (see BlockCompare.h). 
+ *  Function TCompareXX sorts objects 
+ *  by the variable "XX" that MUST be present in the data members of the 
+ *  Block TRoot class.
+ *  By default most objects are sorted by PT or ET.
+ *  Only calorimeter cells and basic cluster are sorted by E
+ *  TRootGenParticle particle is not sorted by default
+ *  to preserve mother-dautherlinks between particles.
+ *
+ *  $Date: 2008-11-04 10:32:26 $
+ *  $Revision: 1.1 $
+ *
+ *  
+ *  \author S. Ovyn - UCL, Louvain-la-Neuve
+ *
+ */
+
+#include "Utilities/ExRootAnalysis/interface/BlockClasses.h"
+#include "Utilities/ExRootAnalysis/interface/BlockCompare.h"
+
+TCompare *TRootGenParticle::fgCompare = 0;
+TCompare *TRootJet::fgCompare = TComparePT<TRootJet>::Instance();
+TCompare *TRootElectron::fgCompare = TComparePT<TRootElectron>::Instance();
+TCompare *TRootMuon::fgCompare = TComparePT<TRootMuon>::Instance();
+TCompare *TRootPhoton::fgCompare = TComparePT<TRootPhoton>::Instance();
+TCompare *TRootTauJet::fgCompare = TComparePT<TRootTauJet>::Instance();
+TCompare *TRootTracks::fgCompare = TComparePT<TRootTracks>::Instance();
+TCompare *TRootETmis::fgCompare = 0;
+TCompare *TRootCalo::fgCompare = 0;
+TCompare *TRootZdcHits::fgCompare = 0;
+TCompare *TRootGenEvent:: fgCompare = 0;
+TCompare *TRootParticle::fgCompare=0;
+TCompare *TRootLHEFParticle::fgCompare = 0;
+TCompare *TRootRomanPotHits::fgCompare =0;
+
+void TRootParticle::Set(const TLorentzVector& momentum) {
+	E   = momentum.E();
+	Px  = momentum.Px();
+	Py  = momentum.Py();
+	Pz  = momentum.Pz();
+	PT  = momentum.Pt();
+	Eta = momentum.Eta();
+	Phi = momentum.Phi();
+}
+
Index: /trunk/Utilities/ExRootAnalysis/src/BlockClassesLinkDef.h
===================================================================
--- /trunk/Utilities/ExRootAnalysis/src/BlockClassesLinkDef.h	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/src/BlockClassesLinkDef.h	(revision 3)
@@ -0,0 +1,42 @@
+
+/** \class BlockClassesLinkDef
+ *
+ *  Lists classes to be included in cint dicitonary
+ *
+ *  $Date: 2008-11-04 10:32:26 $
+ *  $Revision: 1.1 $
+ *
+ *  
+ *  \author S. Ovyn - UCL, Louvain-la-Neuve
+ *
+ */
+
+#include "Utilities/ExRootAnalysis/interface/BlockClasses.h"
+
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class TSortableObject;
+#pragma link C++ class TRootSelectorInfo;
+#pragma link C++ class TRootGenParticle;
+#pragma link C++ class TRootJet;
+#pragma link C++ class TRootElectron;
+#pragma link C++ class TRootMuon;
+#pragma link C++ class TRootPhoton;
+#pragma link C++ class TRootTauJet;
+#pragma link C++ class TRootTracks;
+#pragma link C++ class TRootETmis;
+#pragma link C++ class TRootCalo;
+#pragma link C++ class TRootGenEvent;
+#pragma link C++ class TRootZdcHits;
+#pragma link C++ class TRootRomanPotHits;
+
+#pragma link C++ class TRootParticle;
+#pragma link C++ class TRootLHEFEvent+;
+#pragma link C++ class TRootLHEFParticle+;
+
+
+#endif
Index: /trunk/Utilities/ExRootAnalysis/src/ExRootProgressBar.cc
===================================================================
--- /trunk/Utilities/ExRootAnalysis/src/ExRootProgressBar.cc	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/src/ExRootProgressBar.cc	(revision 3)
@@ -0,0 +1,82 @@
+
+/** \class ExRootProgressBar
+ *
+ *  Class showing progress bar
+ *
+ *  $Date: 2008-11-04 10:32:27 $
+ *  $Revision: 1.1 $
+ *
+ *
+ *  \author P. Demin - UCL, Louvain-la-Neuve
+ *
+ */
+
+#include "Utilities/ExRootAnalysis/interface/ExRootProgressBar.h"
+
+#include "TSystem.h"
+
+#include <iostream>
+
+#include <string.h>
+#include <stdio.h>
+
+using namespace std;
+
+ExRootProgressBar::ExRootProgressBar(Long64_t entries, Int_t width) :
+  fEntries(entries), fWidth(width), fTime(0), fHashes(0), fBar(0)
+{
+  fBar = new char[width + 1];
+  memset(fBar, '-', width);
+  fBar[width] = 0;
+
+}
+
+//------------------------------------------------------------------------------
+
+ExRootProgressBar::~ExRootProgressBar()
+{
+  if(fBar) delete[] fBar;
+}
+
+//------------------------------------------------------------------------------
+
+void ExRootProgressBar::Update(Long64_t entry)
+{
+  ULong_t time = gSystem->Now();
+
+  if(time < fTime + 1000 && entry < fEntries - 1) return;
+
+  fTime = time;
+
+  Int_t hashes = Int_t((entry + 1.0)/fEntries*fWidth);
+
+  if(hashes > fHashes)
+  {
+    memset(fBar + fHashes, '#', hashes - fHashes);
+    fHashes = hashes;
+  }
+
+/*
+  cerr << "[" << fBar << "] (";
+  cerr.setf(ios::fixed);
+  cerr.precision(2);
+  cerr << (entry + 1.0)/fEntries*100.0 << "%) : ";
+  cerr << entry + 1 << "/" << fEntries;
+  cerr << " events processed\r" << flush;
+*/
+
+  fprintf(stderr, "[%s] (%.2f%%) : %lli/%lli entries processed\r", fBar,
+          (entry + 1.0)/fEntries*100.0, entry + 1, fEntries);
+  fflush(stderr);
+}
+
+//------------------------------------------------------------------------------
+
+void ExRootProgressBar::Finish()
+{
+  fprintf(stderr, "\n");
+  fflush(stderr);
+}
+
+//------------------------------------------------------------------------------
+
Index: /trunk/Utilities/ExRootAnalysis/src/ExRootTreeBranch.cc
===================================================================
--- /trunk/Utilities/ExRootAnalysis/src/ExRootTreeBranch.cc	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/src/ExRootTreeBranch.cc	(revision 3)
@@ -0,0 +1,86 @@
+
+/** \class ExRootTreeBranch
+*
+*  Class handling output ROOT tree branch
+*
+*  $Date: 2008-11-04 10:32:27 $
+*  $Revision: 1.1 $
+*
+*
+*  \author S. Ovyn - UCL, Louvain-la-Neuve
+*
+*/
+
+#include "Utilities/ExRootAnalysis/interface/ExRootTreeBranch.h"
+
+#include "TFile.h"
+#include "TTree.h"
+#include "TClonesArray.h"
+
+#include <iostream>
+
+using namespace std;
+
+//------------------------------------------------------------------------------
+
+ExRootTreeBranch::ExRootTreeBranch(const TString &name, TClass *cl, TTree *tree) :
+  fSize(0), fCapacity(1), fData(0)
+{
+  cl->IgnoreTObjectStreamer();
+  fData = new TClonesArray(cl, fCapacity);
+
+  if(fData)
+  {
+    fData->ExpandCreateFast(fCapacity);
+    fData->Clear();
+    tree->Branch(name, &fData, 64000);
+    tree->Branch(name + "_size", &fSize, name + "_size/I");
+  }
+  else
+  {
+    throw MemoryAllocationExeption();
+  }
+}
+
+//------------------------------------------------------------------------------
+
+ExRootTreeBranch::~ExRootTreeBranch()
+{
+  if(fData) delete fData;
+}
+
+//------------------------------------------------------------------------------
+
+TObject *ExRootTreeBranch::NewEntry()
+{
+  if(!fData) return 0;
+
+  if(fSize >= fCapacity)
+  {
+    Int_t entry;
+
+    if(fCapacity < 10) fCapacity = 10;
+    else if(fCapacity < 30) fCapacity = 30;
+    else if(fCapacity < 100) fCapacity = 100;
+    else if(fCapacity < 250) fCapacity = 250;
+    else fCapacity *= 2;
+
+    fData->ExpandCreateFast(fCapacity);
+
+    fData->Clear();
+    for(entry = 0; entry < fSize; ++entry) fData->AddrAt(entry);
+  }
+  
+  return fData->AddrAt(fSize++);
+}
+
+//------------------------------------------------------------------------------
+
+void ExRootTreeBranch::Clear()
+{
+  fSize = 0;
+  if(fData) fData->Clear();
+}
+
+//------------------------------------------------------------------------------
+
Index: /trunk/Utilities/ExRootAnalysis/src/ExRootTreeReader.cc
===================================================================
--- /trunk/Utilities/ExRootAnalysis/src/ExRootTreeReader.cc	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/src/ExRootTreeReader.cc	(revision 3)
@@ -0,0 +1,163 @@
+
+/** \class ExRootTreeReader
+ *
+ *  Class simplifying access to ROOT tree branches
+ *
+ *  $Date: 2008-11-04 10:32:27 $
+ *  $Revision: 1.1 $
+ *
+ *
+ *  \author S. Ovyn - UCL, Louvain-la-Neuve
+ *
+ */
+
+#include "Utilities/ExRootAnalysis/interface/ExRootTreeReader.h"
+
+#include "TH2.h"
+#include "TStyle.h"
+#include "TCanvas.h"
+#include "TBranchElement.h"
+#include "TClonesArray.h"
+
+#include <iostream>
+
+using namespace std;
+
+//------------------------------------------------------------------------------
+
+ExRootTreeReader::ExRootTreeReader(TTree *tree) :
+  fChain(tree), fCurrentTree(-1), fIsInitDone(kFALSE)
+{
+
+}
+
+//------------------------------------------------------------------------------
+
+ExRootTreeReader::~ExRootTreeReader()
+{
+  TBranchMap::iterator it_map;
+
+  for(it_map = fBranchMap.begin(); it_map != fBranchMap.end(); ++it_map)
+  {
+    delete it_map->second.second;
+  }
+}
+
+//------------------------------------------------------------------------------
+
+Bool_t ExRootTreeReader::ReadEntry(Long64_t entry)
+{
+  // Read contents of entry.
+  if(!fChain) return kFALSE;
+
+  if(!fIsInitDone) Init();
+
+  Int_t treeEntry = fChain->LoadTree(entry);
+  if(treeEntry < 0) return kFALSE;
+  
+  if(fChain->IsA() == TChain::Class())
+  {
+    TChain *chain = static_cast<TChain*>(fChain);
+    if(chain->GetTreeNumber() != fCurrentTree)
+    {
+      fCurrentTree = chain->GetTreeNumber();
+      Notify();
+    }
+  }
+
+  TBranchMap::iterator it_map;
+  TBranch *branch;
+
+  for(it_map = fBranchMap.begin(); it_map != fBranchMap.end(); ++it_map)
+  {
+    branch = it_map->second.first;
+    if(branch)
+    {
+      branch->GetEntry(treeEntry);
+    }
+  }
+
+  return kTRUE;
+}
+
+//------------------------------------------------------------------------------
+
+TClonesArray *ExRootTreeReader::UseBranch(const TString &branchName)
+{
+  fIsInitDone = kFALSE;
+
+  TClonesArray *array = 0;
+
+  TBranchMap::iterator it_map = fBranchMap.find(branchName);
+
+  if(it_map != fBranchMap.end())
+  {
+    array = it_map->second.second;
+  }
+  else
+  {
+    TBranch *branch = fChain->GetBranch(branchName);
+    if(branch)
+    {
+      if(branch->IsA() == TBranchElement::Class())
+      {
+        TBranchElement *element = static_cast<TBranchElement*>(branch);
+        const char *className = element->GetClonesName();
+        Int_t size = element->GetMaximum();
+        TClass *cl = gROOT->GetClass(className);
+        if(cl)
+        {
+          array = new TClonesArray(cl, size);
+          fBranchMap.insert(make_pair(branchName, make_pair(branch, array)));
+        }
+      }
+    }
+  }
+
+  if(!array)
+  {
+    cout << "** WARNING: cannot access branch '" << branchName << "', return NULL pointer" << endl;
+  }
+
+  return array;
+}
+
+//------------------------------------------------------------------------------
+
+void ExRootTreeReader::Init()
+{
+  TBranchMap::iterator it_map;
+
+  for(it_map = fBranchMap.begin(); it_map != fBranchMap.end(); ++it_map)
+  {
+    fChain->SetBranchAddress(it_map->first, &(it_map->second.second));
+  }
+
+  Notify();
+
+  fIsInitDone = kTRUE;
+}
+
+//------------------------------------------------------------------------------
+
+void ExRootTreeReader::Notify()
+{
+  // Called when loading a new file.
+  // Get branch pointers.
+  if(!fChain) return;
+
+  TBranchMap::iterator it_map;
+
+  for(it_map = fBranchMap.begin(); it_map != fBranchMap.end(); ++it_map)
+  {
+    it_map->second.first = fChain->GetBranch(it_map->first);
+    if(!it_map->second.first)
+    {
+      cout << "** WARNING: cannot get branch '" << it_map->first << "'" << endl;
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+
+
Index: /trunk/Utilities/ExRootAnalysis/src/ExRootTreeWriter.cc
===================================================================
--- /trunk/Utilities/ExRootAnalysis/src/ExRootTreeWriter.cc	(revision 3)
+++ /trunk/Utilities/ExRootAnalysis/src/ExRootTreeWriter.cc	(revision 3)
@@ -0,0 +1,93 @@
+
+/** \class ExRootTreeWriter
+ *
+ *  Class handling output ROOT tree
+ *
+ *  $Date: 2008-11-04 10:32:27 $
+ *  $Revision: 1.1 $
+ *
+ *
+ *  \author S. Ovyn - UCL, Louvain-la-Neuve
+ *
+ */
+
+#include "Utilities/ExRootAnalysis/interface/ExRootTreeWriter.h"
+#include "Utilities/ExRootAnalysis/interface/ExRootTreeBranch.h"
+
+#include "TROOT.h"
+#include "TFile.h"
+#include "TTree.h"
+#include "TClonesArray.h"
+
+#include <iostream>
+
+using namespace std;
+
+ExRootTreeWriter::ExRootTreeWriter(const TString &fileName, const TString &treeName)
+{
+  TDirectory *dir = gDirectory;
+  fNewFile = TFile::Open(fileName,"UPDATE");
+  fNewFile->cd();
+  fNewTree = new TTree(treeName, "Analysis tree");
+  dir->cd();
+  
+  if(!fNewTree)
+  {
+    cout << "** ERROR: cannot create tree" << endl;
+    return;
+  }
+
+  fNewTree->SetAutoSave(10000000);  // autosave when 10 MB written
+}
+
+//------------------------------------------------------------------------------
+
+ExRootTreeWriter::~ExRootTreeWriter()
+{
+  set<ExRootTreeBranch*>::iterator it_set;
+  for(it_set = fBranches.begin(); it_set != fBranches.end(); ++it_set)
+  {
+    delete (*it_set);
+  }
+  
+  if(fNewTree) delete fNewTree;
+  if(fNewFile) delete fNewFile;  
+}
+
+//------------------------------------------------------------------------------
+
+ExRootTreeBranch *ExRootTreeWriter::NewBranch(const TString &name, TClass *cl)
+{
+  ExRootTreeBranch *branch = new ExRootTreeBranch(name, cl, fNewTree);
+  fBranches.insert(branch);
+  return branch;
+}
+
+//------------------------------------------------------------------------------
+
+void ExRootTreeWriter::Fill()
+{
+  if(fNewTree) fNewTree->Fill();
+}
+
+//------------------------------------------------------------------------------
+
+void ExRootTreeWriter::Write()
+{
+  fNewFile = fNewTree ? fNewTree->GetCurrentFile() : 0;
+  if(fNewFile) fNewFile->Write();
+}
+
+//------------------------------------------------------------------------------
+
+void ExRootTreeWriter::Clear()
+{
+  set<ExRootTreeBranch*>::iterator it_set;
+  for(it_set = fBranches.begin(); it_set != fBranches.end(); ++it_set)
+  {
+    (*it_set)->Clear();
+  }
+}
+
+//------------------------------------------------------------------------------
+
Index: /trunk/Utilities/Hector/CREDITS
===================================================================
--- /trunk/Utilities/Hector/CREDITS	(revision 3)
+++ /trunk/Utilities/Hector/CREDITS	(revision 3)
@@ -0,0 +1,13 @@
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+
+   HECTOR, a fast simulator for the transport of particles in beamlines, 
+   JINST 2 P09005, X. Rouby, J. de Favereau, K. Piotrzkowski
+
+   arXiv:0707.1198v2 [physics.acc-ph] (CP3-07-13)
Index: /trunk/Utilities/Hector/VERSION
===================================================================
--- /trunk/Utilities/Hector/VERSION	(revision 3)
+++ /trunk/Utilities/Hector/VERSION	(revision 3)
@@ -0,0 +1,1 @@
+_1_4_0
Index: /trunk/Utilities/Hector/include/H_AbstractBeamLine.h
===================================================================
--- /trunk/Utilities/Hector/include/H_AbstractBeamLine.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_AbstractBeamLine.h	(revision 3)
@@ -0,0 +1,140 @@
+#ifndef _H_AbstractBeamLine_
+#define _H_AbstractBeamLine_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+	http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de Phï¿œnomï¿œnologie (CP3)
+   Universitï¿œ Catholique de Louvain (UCL)
+*/
+
+/// \file H_AbstractBeamLine.h
+/// \brief Class aiming at simulating the LHC beamline.
+///
+/// Units : angles [ï¿œrad], distances [ï¿œm], energies [GeV], c=[1].
+
+	/// default length of the beam line
+#define LENGTH_DEF 100
+
+// c++ #includes
+#include <vector>
+#include <algorithm>
+#include <string>
+
+
+// ROOT #includes
+#include "TMatrix.h"
+#include "TGraph.h"
+
+// local #includes
+#include "H_OpticalElement.h"
+using namespace std;
+
+/// Beamline made from a vector of H_OpticalElement.
+class H_AbstractBeamLine {
+
+	public:
+		void init(const float );
+		///     Constructors, destructor and operator
+		//@{
+		H_AbstractBeamLine() {init(LENGTH_DEF);};
+		H_AbstractBeamLine(const float length) {init(length);};
+		H_AbstractBeamLine(const H_AbstractBeamLine &);
+		H_AbstractBeamLine& operator=(const H_AbstractBeamLine&);
+		H_AbstractBeamLine* clone() const ;
+		~H_AbstractBeamLine();
+		//@}
+		///     Adds an element to the beamline
+		//@{
+		void add(H_OpticalElement *);
+		void add(H_OpticalElement &);
+		//@}
+		///     Returns the (float) length of the beamline
+  		inline float getLength() const { return beam_length;};
+		///     Returns the (int) number of optics element of the beamline, including drifts
+  		inline int getNumberOfElements() const { return (int)elements.size();}; 
+		///     Returns the transport matrix for the whole beam
+		const TMatrix getBeamMatrix() const;
+		///     Returns the transport matrix for the whole beam, for given energy loss/mass/charge
+		const TMatrix getBeamMatrix(const float , const float, const float ) ;
+		///     Returns the transport matrix for a part of the beam from the IP to a given element
+		const TMatrix getPartialMatrix(const H_OpticalElement *) const;
+		///     Returns the transport matrix for a part of the beam from the IP to the ith element
+		const TMatrix getPartialMatrix(const unsigned int ) const;
+		///     Returns the transport matrix for a part of the beam from the IP to a given element, given energy loss/mass/charge
+		const TMatrix getPartialMatrix(const string, const float, const float, const float);
+		///     Returns the ith element of the beamline
+		//@{
+		H_OpticalElement * getElement(const unsigned int );
+		H_OpticalElement * getElement(const unsigned int ) const;
+		//@}
+		///	Returns a given element of the beamline, choosen by name 
+		//@{
+		H_OpticalElement * getElement(const string );
+		H_OpticalElement * getElement(const string ) const;
+		//@}
+		///	Print some info
+		void printProperties() const;
+		///     Prints the element list
+		void showElements() const;
+		///     Prints the list of elements of a give type
+		void showElements(const int) const;
+		///     Prints the transport matrix for the whole beam
+		void showMatrix() const;
+		///     Prints the transport matrix for each element of the beamline
+		void showMatrices() const;
+		/// 	Reorders elements and adds the drift sections
+		void calcSequence();
+		/// 	Computes global transport matrix
+		void calcMatrix();
+		/// 	Draws the legend of the elements of the beam
+		void draw(const float xmin =0.85, const float ymin=0.5, const float xmax=1, const float ymax=1) const;
+		/// 	Draws the elements of the beam in the (x,s) plane
+		void drawX(const float, const float, const float scale=1) const;
+		/// 	Draws the elements of the beam in the (y,s) plane
+		void drawY(const float, const float) const;
+		///	Moves an element in the list, reorders the lists and recomputes the transport matrix
+		void moveElement(const string, const float ); 
+		/// Moves the given element tranversely by given amounts.
+		void alignElement(const string, const float, const float);
+		/// Tilts the given element tranversely by given angles.
+		void tiltElement(const string, const float, const float);
+		///	Offsets all element in X pos from the start position
+		void offsetElements(const float start, const float offset);
+		///	Draws the beta functions, from MAD
+		//@{
+		TGraph * getBetaX() const;
+		TGraph * getBetaY() const;
+		//@}
+                ///     Draws the dispersion functions, from MAD
+                //@{
+                TGraph * getDX() const;
+                TGraph * getDY() const;
+                //@}
+                ///     Draws the relative position functions, from MAD
+                //@{
+                TGraph * getRelX() const;
+                TGraph * getRelY() const;
+                //@}
+
+
+	private:
+	        /// list of all optics elements, including drifts
+		vector<H_OpticalElement*> elements; 
+        	/// list of matrices, 1 matrix = the transport till the end of each element
+		vector<TMatrix> matrices; 
+	        /// transport matrix for the whole beam
+		TMatrix beam_mat;		    	
+		/// Orderting method for the vector of H_OpticalElement*
+		struct ordering{ bool operator()(H_OpticalElement* el1, H_OpticalElement* el2) const { return (*el1 < *el2);}};
+
+	protected:
+		/// total length of the beamline
+		float beam_length;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_Aperture.h
===================================================================
--- /trunk/Utilities/Hector/include/H_Aperture.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_Aperture.h	(revision 3)
@@ -0,0 +1,81 @@
+#ifndef _H_Aperture_
+#define _H_Aperture_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Aperture.h
+/// \brief Defines the aperture of beamline elements.
+
+// C++ #defines
+#include <string>
+using namespace std;
+
+// local #defines
+#define NONE        0
+#define RECTANGULAR 1
+#define ELLIPTIC    2
+#define CIRCULAR    3
+#define RECTELLIPSE 4
+#define NONENAME        "None       "
+#define RECTANGULARNAME "Rectangle  "
+#define ELLIPTICNAME    "Ellipse    "
+#define CIRCULARNAME    "Circle     "
+#define RECTELLIPSENAME "Rectellipse"
+
+/// Defines the aperture of any optics element.
+class H_Aperture {
+
+	public:
+		/// Constructors, destructor and operators
+		//@{
+		H_Aperture();
+		H_Aperture(const int, const float, const float, const float, const float, const float, const float);
+		H_Aperture(const H_Aperture&);
+		H_Aperture& operator=(const H_Aperture&);
+		virtual ~H_Aperture() { return; };
+		virtual H_Aperture* clone() const { return new H_Aperture(type,x1,x2,x3,x4,fx,fy); };
+		//@}
+
+		/// Prints the aperture features
+		virtual void printProperties() const;
+		/// Draws the aperture shape
+		virtual void draw(const float scale=1) const {return;};
+		/// Sets the (x,y) position in [m]
+		void setPosition(const float,const float);
+		/// Checks whether the point is inside the aperture or not
+		virtual bool isInside(const float, const float) const; 
+		/// Returns the (int) type of aperture
+		inline int getType() const {return type;};
+		/// Returns the (string) type of the aperture
+		inline const string getTypeString() const { return aptypestring; }
+		
+	
+	protected:
+		/// Aperture shape (either RECTANGULAR or ELLIPTIC or ...)
+		int type;
+		/// Aperture shape string
+		string aptypestring;
+
+		/// Aperture geometrical sizes (length/width or great/small radii) [m]
+		//@{
+		float x1, x2, x3, x4; 
+		//@}
+
+		/// Horizontal coordinate of the aperture center [m] (from the nominal beam position).
+		//@{
+		float fx, fy;
+		//@}
+		/// Sets the name of the aperture from its type.
+		void setApertureString();
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_Beam.h
===================================================================
--- /trunk/Utilities/Hector/include/H_Beam.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_Beam.h	(revision 3)
@@ -0,0 +1,189 @@
+#ifndef _H_Beam_
+#define _H_Beam_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Beam.h
+/// \brief Describes a set a particles as a beam
+///
+
+// c++ #includes
+//#include <iostream>
+#include <vector>
+#include <sstream>
+#include <cmath>
+
+// ROOT #includes
+#include "TH2F.h"
+#include "TGraphErrors.h"
+#include "TMultiGraph.h"
+
+// local #includes
+#include "H_BeamParticle.h"
+#include "H_AbstractBeamLine.h"
+#include "H_Parameters.h"
+#include "H_OpticalElement.h"
+using namespace std;
+
+/// \brief Beam made from a STL vector of H_BeamParticle.
+///
+/// Example of usage :
+/// <PRE>
+///   H_Beam mybeam;
+///   mybeam.createBeamParticles(100);
+///   H_AbstractBeamLine * beamline = new H_AbstractBeamLine(200);
+///	... (<-- fills the beam)
+///   mybeam.computePath(beamline)
+/// </PRE>
+class H_Beam {
+
+	public:
+	/// Constructors, destructor and operator
+	//@{
+		H_Beam();
+		H_Beam(const H_Beam&);
+		H_Beam& operator=(const H_Beam&);
+		~H_Beam();
+	//@}
+        /// Fills the beam with particles in given position/angle/energy        intervals (flat distribution)
+                //void particleGun(const unsigned int Number_of_particles, const float E_min, const float E_max, const float fs_min, const float fs_max, const float fx_min, const float fx_max, const float fy_min, const float fy_max, const float tx_min, const float tx_max, const float ty_min, const float ty_max, const float p_mass, const double p_charge);
+                void particleGun(const unsigned int Number_of_particles, const float E_min=BE, const float E_max=BE, const float fs_min=0, const float fs_max=0, const float fx_min=0, const float fx_max=0, const float fy_min=0, const float fy_max=0, const float tx_min=-PI/2., const float tx_max=PI/2., const float ty_min=-PI/2., const float ty_max=PI/2., const float p_mass=MP, const double p_charge=QP, const bool flat = true);
+
+	/// Fills the beam with particles
+	//@{
+		void createBeamParticles(const unsigned int , const double , const double );
+		void createBeamParticles(const unsigned int);
+	//@}
+	/// Fills the beam with particles with incremental offset and no initial transverse momentum
+	//@{
+		void createXScanningBeamParticles(const unsigned int, const float);
+		void createYScanningBeamParticles(const unsigned int, const float);
+	//@}
+	/// Fills the beam with particles with incremental initial angle and no offset.
+	//@{
+		void createTXScanningBeamParticles(const unsigned int, const float);
+		void createTYScanningBeamParticles(const unsigned int, const float);
+	//@}
+	/// Returns the ith particle
+	//@{
+		const H_BeamParticle * getBeamParticle(const unsigned int ) const;
+		H_BeamParticle * getBeamParticle(const unsigned int );
+	//@}
+	/// Adds a particle to the beam
+		void add(const H_BeamParticle&);
+	/// Compute the position of each particle in the beamline
+	//@{	
+		void computePath(const H_AbstractBeamLine *, const bool);
+		void computePath(const H_AbstractBeamLine *);
+	//@}
+	// Photon emission by the particle
+	// @{
+                void emitGamma(const double, const double, const double, const double);
+		void emitGamma(const double, const double);
+	//@}
+	// Propagates the beam until a given s
+		void propagate(const float );
+	/// Returns the \f$ \beta \f$ function of the beam
+	//@{
+		float getBetaX(const float , float& );
+                float getBetaY(const float , float& );
+	//@}
+	/// Draws the \f$ \beta \f$ function of the beam
+	//@{
+		TGraphErrors  * getBetaX(const float, const unsigned int);
+		TGraphErrors  * getBetaY(const float, const unsigned int);
+	//@}
+        /// Returns the position of the beam
+	//@{
+                float getX(const float , float& );
+                float getY(const float , float& );
+	//@}
+	/// Returns the emittance \f$ \epsilon \f$ of the beam in x and y
+	//@{
+	inline const float getEmittanceX() const {
+			if(!x_disp*tx_disp) cout<<"Warning : Degenerate Beam : x-emittance = 0"<<endl; 	
+			return x_disp * tan(tx_disp/URAD)/URAD;
+		}
+        inline const float getEmittanceY() const { 
+			if(!y_disp*ty_disp) cout<<"Warning : Degenerate Beam : y-emittance = 0"<<endl;
+			return y_disp * tan(ty_disp/URAD)/URAD;
+		}
+	//@}
+	/// Sets the initial parameters of the beam \f$ s , x , y , \theta_x , \theta_y \f$
+	//@{
+		void setS(const float fs) { fs_ini = fs;}
+		void setX(const float fx) { fx_ini = fx;}
+		void setY(const float fy) { fy_ini = fy;}
+		void setTX(const float tx) { tx_ini = tx;}
+		void setTY(const float ty) { ty_ini = ty;}
+		void setE(const float fe) {fe_ini = fe;}
+		void setPosition(const float fx, const float fy, const float tx, const float ty, const float fs) {setS(fs); setX(fx); setY(fy); setTX(tx); setTY(ty);}
+	//@}
+	/// Sets the initial divergence of the beam \f$ \sigma_x , \sigma_y , \sigma (\theta_x), \sigma(\theta_y) \f$
+	//@{
+		void setDS(const float ds) {s_disp = ds;}
+		void setDX(const float dx) {x_disp = dx;}
+		void setDY(const float dy) {y_disp = dy;}
+		void setDTX(const float dtx) {tx_disp = dtx;}
+		void setDTY(const float dty) {ty_disp = dty;}
+		void setDE(const float de) {e_disp = de;}
+		void setDispersion(const float dx, const float dy, const float dtx, const float dty, const float ds) {setDS(ds); setDX(dx); setDY(dy); setDTX(dtx); setDTY(dty);}
+	//@} 
+	/// Returns the number of particles which have been stopped
+		unsigned int getStoppedNumber(const H_AbstractBeamLine *);
+	/// Returns the list of the stopping elements in the beamline
+		vector<TVectorD> getStoppingElements(const H_AbstractBeamLine *, vector<H_OpticalElement>&, vector<int>&);
+	/// Prints the initial parameters
+		void printInitialState() const;
+	/// Prints the properties for each particle
+		void printProperties() const;
+	/// Prints the list of the stopping elements in the beamline
+		void printStoppingElements(const vector<H_OpticalElement>&, const vector<int>&) const;
+	/// Returns the number of particle is this beam
+		const int getNumberOfBeamParticles() const {return Nparticles;}
+	/// Draws the beam profile at a given s
+		TH2F * drawProfile(const float);
+		TH2F * drawAngleProfile(const float);
+	/// Draws the beam width and height
+	//@{
+		TMultiGraph * drawBeamX(const int) const;
+		TMultiGraph * drawBeamY(const int) const ;
+	//@}
+
+	protected:
+	/// List of particles
+		vector<H_BeamParticle> beamParticles;
+	/// IP position
+	//@{
+		float fx_ini, fy_ini, fs_ini;
+	//@}
+	/// IP \f$ \theta \f$ (angular) position
+	//@{
+		float tx_ini, ty_ini;
+	//@}
+	/// nominal beam energy
+		float fe_ini;
+	/// dispersion in position
+	//@{
+		float x_disp, y_disp, s_disp;
+	//@}
+	/// dispersion in \f$ \theta \f$
+	//@{
+		float tx_disp, ty_disp;
+	//@}
+	/// dispersion in energy
+		float e_disp;
+	/// Number of particles in this beam
+		unsigned int Nparticles;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_BeamLine.h
===================================================================
--- /trunk/Utilities/Hector/include/H_BeamLine.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_BeamLine.h	(revision 3)
@@ -0,0 +1,65 @@
+#ifndef _H_BeamLine_
+#define _H_BeamLine_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_BeamLine.h
+/// \brief Class aiming at retrieving features of the real beam optical elements.
+
+// local #includes
+#include "H_AbstractBeamLine.h"
+
+// C++ #includes
+#include <string>
+using namespace std;
+
+// Caution : mad conventions for vertically(horizontally) focusing quadrupoles
+// are opposite to Wille's. See fill() for more details.
+
+/// Reads external files and retrieves features of the real beam optical elements.
+class H_BeamLine : public H_AbstractBeamLine {
+
+	public:
+	///     Constructors and destructor
+	//@{
+		H_BeamLine():H_AbstractBeamLine() {direction=1; ips=0; };
+		H_BeamLine(const H_BeamLine& );
+		H_BeamLine(const int, const float);
+		H_BeamLine& operator=(const H_BeamLine& );
+		~H_BeamLine() {return;};
+	//@
+		///     Finds the IP position (s) from the MAD table. Should be "IP5" or "IP1".
+		//@{
+		void findIP(const string);
+		void findIP(const string, const string);
+		//@}
+		///     Reader for the external MAD table
+		//@{
+		void fill(const string);
+		void fill(const string, const int, const string );
+		//@}
+		///     Returns the IP position (s)
+		double getIP() {return ips;};
+		///		Returns positions and angles of beam at IP
+		double* getIPProperties();
+
+	private:
+		int direction; // to or from the IP.
+		double ips; // s-position of the IP [m]
+		double ipx; // x-position of the IP [Âµm]
+		double ipy; // y-position of the IP [Âµm]
+		double iptx; // x-angle of momentum at IP [Âµrad]
+		double ipty; // y-angle of momentum at IP [Âµrad]
+};
+
+#endif
+
Index: /trunk/Utilities/Hector/include/H_BeamLineParser.h
===================================================================
--- /trunk/Utilities/Hector/include/H_BeamLineParser.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_BeamLineParser.h	(revision 3)
@@ -0,0 +1,117 @@
+#ifndef _H_BeamLineParser_
+#define _H_BeamLineParser_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_BeamLineParser.h
+/// \brief Reader for madx tables
+///
+/// Notes : Verifier que tous les SBEND sont toujours appeles MB. Et seulement comme ca !
+/// Verifier qu'il n'y a pas de probleme d'inversion H/V QUADRUPOLES
+/// no distinction between H and Vkickers ?
+/// The identification of the element is based on the values of k1l, k2l, hkick, vkick and on their name.
+
+// c++ #includes
+#include <iostream>
+#include <string>
+#include <fstream>
+#include <sstream>
+using namespace std;
+
+// local defines
+#define MADX_UNKNOWN 0
+#define MADX_NAME    1
+#define MADX_KEYWORD 2
+#define MADX_S       3
+#define MADX_L       4
+#define MADX_K0L     5
+#define MADX_K1L     6
+#define MADX_K2L     7
+#define MADX_K3L     8
+#define MADX_HKICK   9
+#define MADX_VKICK  10
+#define MADX_BETX   11
+#define MADX_ALFX   12
+#define MADX_MUX    13
+#define MADX_DX     14
+#define MADX_DPX    15
+#define MADX_X      16
+#define MADX_PX     17
+#define MADX_BETY   18
+#define MADX_ALFY   19
+#define MADX_MUY    20
+#define MADX_DY     21
+#define MADX_DPY    22
+#define MADX_Y      23
+#define MADX_PY     24
+#define MADX_APERTYPE 25
+#define MADX_APER_1 26
+#define MADX_APER_2 27
+#define MADX_APER_3 28
+#define MADX_APER_4 29
+#define MADX_KICK 30
+#define MADX_PARENT 31
+/* Apertures # parameters
+	CIRCLE 1
+	ELLIPSE	2
+	RECTANGLE	2
+	LHCSCREEN	3
+	MARGUERITE	3
+	RECTELLIPSE	4
+	RACETRACK	3
+*/
+
+extern int column_identification(const string );
+
+/// \brief Reader for madx tables to use in H_BeamLine
+///
+/// More info on http://project-mad9.web.cern.ch/project-mad9/mad/mad9/user/index.html
+class H_BeamLineParser {
+
+	public:
+	/// Constructor and destructor
+	//@{
+		H_BeamLineParser() {init();}
+		~H_BeamLineParser() {return;}
+	//@}
+		void init();
+		/// Retrieve the data from the line it reads, and sets the corresponding variable.
+		void setProperties(istream& , const unsigned int );
+		void printProperties() const;
+		string name, apertype, keyword, parent;
+		/// Optical element longitudinal (co-moving) coordinate.
+		double s;
+		/// Length of the element.
+		double l;
+	/// Magnetic field strength.
+	//@{
+		double k0l, k1l, k2l, k3l, hkick, vkick;
+	//@}
+	/// Phase (mu), \f$ \alpha \f$(alf) and \f$ \beta \f$(bet) functions, given by MAD.
+	//@{
+		double mux, muy, betx, alfx, bety, alfy;
+	//@}
+	/// Positions and their dispersion
+	//@{ 
+		double x, y, dx, dy;
+	//@}
+	/// Momentum and their dispersion
+	//@{
+		double px, py, dpx, dpy;
+	//@}
+	/// Aperture parameters
+	//@{
+		double aper_1, aper_2, aper_3, aper_4;
+	//@}
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_BeamParticle.h
===================================================================
--- /trunk/Utilities/Hector/include/H_BeamParticle.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_BeamParticle.h	(revision 3)
@@ -0,0 +1,177 @@
+#ifndef _H_BeamParticle_
+#define _H_BeamParticle_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_BeamParticle.h
+/// \brief Class aiming at simulating a particle in the beamline
+
+// from IP to RP, with emission of a photon of defined energy and Q.
+// Units : angles [rad], distances [m], energies [GeV], masses [GeV], c=[1].
+// !!! no comment statement at the end of a #define line !!!
+
+// c++ #includes
+#include <vector>
+
+// ROOT #includes
+#include "TMatrixD.h"
+#include "TVectorD.h"
+#include "TLorentzVector.h"
+
+// local #includes
+#include "H_Parameters.h"
+#include "H_AbstractBeamLine.h"
+#include "H_OpticalElement.h"
+
+using namespace std;
+
+/// Defines a particle from the beam and its transport through the beamline
+class H_BeamParticle {
+
+	public:
+		void init();
+		/// Constructors and Destructor
+		//@{
+		H_BeamParticle();
+		H_BeamParticle(const H_BeamParticle&);
+		H_BeamParticle(const double, const double);
+		H_BeamParticle& operator=(const H_BeamParticle&);
+		~H_BeamParticle() {if(stop_position) delete stop_position; if(!stop_element) delete stop_element; positions.clear(); return; }
+		//@}
+		/// Smears the (x,y) coordinates of the particle [\f$ \mu m \f$]
+		void smearPos(const double, const double);
+		/// Smears the (x,y) coordinates of the particle (using default values in parameters.h)
+		void smearPos();
+		/// Smears the (x,y) angular coordinates of the particle [\f$ \mu rad \f$]
+		void smearAng(const double, const double);
+		/// Smears the (x,y) angular coordinates of the particle (using default values in parameters.h)
+		void smearAng();
+		/// Smears the Energy of the particle [GeV]
+		void smearE(const double);
+		/// Smears the Energy of the particle (using default values in parameters.h) 
+		void smearE();
+		/// Smears the longitudinal position of the particle [\f$ \mu m \f$]
+		void smearS(const double);
+		/// Smears the longitudinal position of the particle (using default values in parameters.h)
+		void smearS();
+		/// Sets the energy [GeV].
+		void setE(const double);
+		/// Sets the particle 4-momentum \f$ P^\mu \f$
+		void set4Momentum(const double, const double, const double, const double);	
+		/// Sets the particle 4-momentum \f$ P^\mu \f$
+		void set4Momentum(const TLorentzVector&);	
+		/// Clears H_BeamParticle::positions and sets the initial one.
+		void setPosition(const double , const double , const double , const double , const double );
+		/// Returns the particle mass [GeV]
+		double getM() const {return mp;};
+		/// Returns the particle charge [e]
+		double getQ() const {return qp;};
+		/// Returns the current x coordinate [\f$ \mu \f$m]
+		double getX() const {return fx;};
+		/// Returns the current y coordinate [\f$ \mu \f$m]
+		double getY() const {return fy;};
+		/// Returns the current s coordinate [m]
+		inline double getS() const {return fs;};
+		/// Returns the current \f$ \theta_x \f$ angular coordinate [\f$ \mu \f$rad]
+		double getTX() const {return thx;};
+		/// Returns the current \f$ \theta_y \f$ angular coordinate [\f$ \mu \f$rad]
+		double getTY() const {return thy;};
+		/// Returns the current particle energy [GeV]
+		inline double getE() const {return energy;};
+		/// Returns all the positions 
+		vector<TVectorD> getPositions() const {return positions;};
+		bool isPhysical() const {return isphysical;};
+		/// \brief Simulates the emission of a photon in a random direction
+		///
+	        /// For \f$ p_{1} \rightarrow p_{2} \gamma \f$, kinematics imposes that
+	        /// \f$ Q^{2} = E^{2}_{\gamma} -p^{2}_{1} -p^{2}_{2} + 2p_{1}p_{2} cos(\theta)  \f$ where \f$ \theta \f$ is the particle scattering angle and \f$ p_{i} = \|\vec{p_{i}}\| \f$. <BR>
+        	/// So, \f$ Q^{2}_{min} = E^{2}_{\gamma} - (p_{1}+p_{2})^{2} \f$ and \f$ Q^{2}_{max} = E^{2}_{\gamma} - (p_{1}-p_{2})^{2} \f$.<BR>
+	        /// As \f$ E^{2}_{\gamma} - (p_{1}-p_{2})^{2} \f$ could be numerically instable, we use here another form of this formula : <BR>
+        	/// \f$ Q^{2}_{max} = -2 * \big( \frac{M_{p} E_{\gamma}}{p_{1}+p_{2}} \big) \big[ 1 + \frac{E^{2}_{1} + E^{2}_{2} - M^{2}_{p} }{ E_{1} E_{2} + p_{1} p_{2}} \big]    \f$
+		//@{
+		void emitGamma(const double, const double, const double, const double);
+		void emitGamma(const double, const double);
+		//@}
+                /// uses Pythia to generate some inelastic pp->pX collision as background
+		void doInelastic();
+		/// \brief Propagates the particule across the beamline until the s coordinate is reached
+		///
+		/// Caution : "computePath" should be used before any "propagate" call <BR>
+		/// Caution : "stopped" is not included in "propagate" : please run it afterward if needed 
+		void propagate(const double ) ;
+		/// Propagates the particle accross the beamline until a given element
+		void propagate(const H_AbstractBeamLine *, const H_OpticalElement *);
+		/// Propagates the particle accross the beamline until a given element
+		void propagate(const H_AbstractBeamLine *, const string);
+		/// Propagates the particle until the end of the beamline
+		void propagate(const H_AbstractBeamLine *);
+		/// Returns the phase vector of the particle
+		const TMatrixD * getV() const;
+		/// Returns the current phase vector of the particle (in H_BeamParticle::positions)
+		const TVectorD * getPosition(const int ) const;
+		/// Prints the properties of the particle
+		void printProperties() const;
+		/// Prints the phase vector of the particle
+		void printV() const;
+		/// Returns the element where the particle has been stopped
+		const H_OpticalElement * getStoppingElement() const;
+		/// Checks if the particle has been stopped in any element of the beamline
+		bool stopped(const H_AbstractBeamLine *);
+		/// Returns the StopPosition vector
+		inline const TVectorD * getStopPosition() const { return stop_position; };
+		// returns (-1,-1,-1,-1,-1) if not stopped (and then hasstopped is false)
+		/// Shows all the vectors \f$ (x, \theta_x, y, \theta_y ,s) \f$ in H_BeamParticle::positions
+		void showPositions() const; 
+		/// Returns the particle path in the beamline
+		TGraph * getPath(const int , const int ) const;
+		/// Computes the position of the particle at the end of each element of the beam, without non linear effects
+		void computePath(const H_AbstractBeamLine *);
+		/// Computes the position of the particle at the end of each element of the beam.
+		void computePath(const H_AbstractBeamLine *, const bool);
+		/// Computes the position of the particle at the end of each element of the beam.
+		void computePath(const H_AbstractBeamLine &, const bool);
+		/// Clears H_BeamParticle::positions but keeps the initial vector.
+		void resetPath();
+
+	private:
+		/// Particle mass [GeV]
+		double mp;
+		/// Particle charge [e]
+		double qp;
+		/// Longitudinal co-moving coordinate [m]
+		double fs;
+		/// Transverse (horizontal) coordinate [m]
+		double fx;
+		/// Transverse (vertical) coordinate [m]
+		double fy;
+		/// Direction of the 3-momentum in the horizontal plane [rad]
+		double thx;
+		/// Direction of the 3-momentum in the vertical plane [rad]
+		double thy;
+		/// Kinetic energy of the particle [GeV]
+		double energy;
+		/// True if the particle has stopped (i.e. : if the particle transverse position has been out of any optics element aperture). <BR> See H_BeamParticle::stopped method. <BR>Default = false.
+		bool hasstopped;
+		/// True if the particle has lost some (E,Q), i.e. if H_BeamParticle::emitGamma was used. Default = false.
+		bool hasemitted;
+		/// False if the particle has emitted a photon with impossible (E,Q). Default = true.
+		bool isphysical;
+		/// Vector (x,tx,y,ty,s) where the particle has stopped.
+		TVectorD * stop_position; 
+		/// Element of the beamline (H_OpticalElement) where the particle has stopped. 
+		H_OpticalElement * stop_element;
+		/// List of (x,tx,y,ty,s) vectors, after each optical element of the beam
+		vector<TVectorD> positions; // vector (x,tx,y,ty,s) after each optical element of the beam ([m],[rad],[m],[rad],[m])
+		/// Adds a new vector (x,tx,y,ty,s) at the end of H_BeamParticle::positions
+  		void addPosition(const double , const double , const double , const double , const double );
+};
+#endif
Index: /trunk/Utilities/Hector/include/H_CircularAperture.h
===================================================================
--- /trunk/Utilities/Hector/include/H_CircularAperture.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_CircularAperture.h	(revision 3)
@@ -0,0 +1,36 @@
+#ifndef _H_CircularAperture_
+#define _H_CircularAperture_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_CircularAperture.h
+/// \brief Defines the circular aperture of beamline elements.
+
+// local #includes
+#include "H_EllipticAperture.h"
+
+
+/// Circular apertures
+class H_CircularAperture: public H_EllipticAperture {
+
+	public:
+		/// Constructors and destructor
+		//@{
+		H_CircularAperture():H_EllipticAperture(0,0,0,0) {type = CIRCULAR; setApertureString();}
+		H_CircularAperture(const float, const float, const float);
+		~H_CircularAperture() {return;};
+		H_CircularAperture* clone() const;
+		//@}
+		virtual void printProperties() const;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_Dipole.h
===================================================================
--- /trunk/Utilities/Hector/include/H_Dipole.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_Dipole.h	(revision 3)
@@ -0,0 +1,42 @@
+/// \file H_Dipole.h
+/// \brief Class aiming at simulating LHC beam dipoles.
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+#ifndef _H_Dipole_
+#define _H_Dipole_
+
+#include "H_OpticalElement.h"
+
+/// Abstract class aiming at simulating dipoles.
+class H_Dipole : public H_OpticalElement {
+
+	public:
+		/// Constructors and destructor
+		//@{
+		H_Dipole():H_OpticalElement() {}
+		H_Dipole(const int dtype, const double s, const double k, const double l):H_OpticalElement(dtype,s,k,l){}
+		H_Dipole(const string nameE, const int dtype, const double s, const double k, const double l):H_OpticalElement(nameE,dtype,s,k,l){}
+	        virtual ~H_Dipole() {return;};
+		//@}
+		/// Prints the properties of the element
+		virtual void printProperties() const;
+		virtual H_Dipole* clone() const =0;
+		void init();
+
+ 	protected:
+    		virtual void setTypeString() =0;
+	    	virtual void setMatrix(const float, const float, const float) = 0;
+    	
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_Drift.h
===================================================================
--- /trunk/Utilities/Hector/include/H_Drift.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_Drift.h	(revision 3)
@@ -0,0 +1,41 @@
+#ifndef _H_Drift_
+#define _H_Drift_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Drift.h
+/// \brief Class aiming at simulating LHC beam drift.
+
+// local includes
+#include "H_OpticalElement.h"
+
+/// \brief Class aiming at simulating LHC beam drift. 
+class H_Drift : public H_OpticalElement {
+
+	public:
+	/// Constructors and destructor
+	//@{
+			H_Drift():H_OpticalElement(DRIFT,0.,0.,0.) {init();}
+        	H_Drift(const double s, const double l):H_OpticalElement(DRIFT,s,0.,l){init();}
+	        H_Drift(const string nameE, const double s, const double l):H_OpticalElement(nameE,DRIFT,s,0.,l){init();}
+	        ~H_Drift() { return; };
+	//@}
+        	virtual void printProperties() const;
+	        void init();
+			H_Drift* clone() const;
+
+	protected:
+        	virtual void setTypeString() {typestring = DRIFTNAME;};
+	        virtual void setMatrix(const float, const float, const float) ;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_EllipticAperture.h
===================================================================
--- /trunk/Utilities/Hector/include/H_EllipticAperture.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_EllipticAperture.h	(revision 3)
@@ -0,0 +1,39 @@
+#ifndef _H_EllipticAperture_
+#define _H_EllipticAperture_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_EllipticAperture.h
+/// \brief Defines the elliptic aperture of beamline elements.
+
+// local #includes
+#include "H_Aperture.h"
+
+/// Elliptic apertures
+class H_EllipticAperture: public H_Aperture {
+
+	public:
+		/// Constructors and destructors
+		//@{
+		H_EllipticAperture():H_Aperture(ELLIPTIC,0,0,0,0,0,0) {}
+		H_EllipticAperture(const float, const float, const float, const float);
+		~H_EllipticAperture() {return;};
+		virtual H_EllipticAperture* clone() const;
+		//@}
+		/// Checks whether the point is inside the aperture or not
+		virtual bool isInside(const float, const float) const;
+		/// Draws the aperture shape.
+		virtual void draw(const float scale=1) const;
+		virtual void printProperties() const;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_HorizontalKicker.h
===================================================================
--- /trunk/Utilities/Hector/include/H_HorizontalKicker.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_HorizontalKicker.h	(revision 3)
@@ -0,0 +1,40 @@
+/// \file H_HorizontalKicker.h
+/// \brief Classes aiming at simulating horizontal kickers in beamline.
+///
+/// fk [rad] for kickers !!!!
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+#ifndef _H_HorizontalKicker_
+#define _H_HorizontalKicker_
+
+// local #includes
+#include "H_Kicker.h"
+
+/// Horizontal kickers for the beamline.
+class H_HorizontalKicker : public H_Kicker {
+
+	public:
+	/// Constructors and destructor
+	//@{
+		H_HorizontalKicker():H_Kicker(HKICKER,0.,0.,0.) {init();}
+		H_HorizontalKicker(const double s, const double k, const double l) :H_Kicker(HKICKER,s,k,l){init();}
+		H_HorizontalKicker(const string nameE, const double s, const double k, const double l) :H_Kicker(nameE,HKICKER,s,k,l){init();}
+		~H_HorizontalKicker() {return;};
+	//@}
+		H_HorizontalKicker* clone() const;
+	private:
+		virtual void setTypeString() {typestring=HKICKERNAME;};
+		virtual void setMatrix(const float, const float, const float) ;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_HorizontalQuadrupole.h
===================================================================
--- /trunk/Utilities/Hector/include/H_HorizontalQuadrupole.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_HorizontalQuadrupole.h	(revision 3)
@@ -0,0 +1,38 @@
+#ifndef _H_HorizontalQuadrupole_
+#define _H_HorizontalQuadrupole_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_HorizontalQuadrupole.h
+/// \brief Class describing horizontally focussing quadrupoles.
+
+// local #includes
+#include "H_Quadrupole.h"
+
+/// Horizontally focussing quadrupoles.
+class H_HorizontalQuadrupole : public H_Quadrupole {
+
+	public:
+	///     Constructors and destructor
+	//@{
+		H_HorizontalQuadrupole():H_Quadrupole(HQUADRUPOLE,0.,0.,0.) {init();}
+		H_HorizontalQuadrupole(const double s, const double k, const double l) : H_Quadrupole(HQUADRUPOLE,s,k,l){init();}
+		H_HorizontalQuadrupole(const string nameE, const double s, const double k, const double l) : H_Quadrupole(nameE,HQUADRUPOLE,s,k,l){init();}
+		~H_HorizontalQuadrupole() {return;};
+	//@}
+		H_HorizontalQuadrupole* clone() const ;
+	private:
+		virtual void setTypeString() {typestring = HQUADRUPOLENAME;};
+		virtual void setMatrix(const float, const float, const float) ;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_Kicker.h
===================================================================
--- /trunk/Utilities/Hector/include/H_Kicker.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_Kicker.h	(revision 3)
@@ -0,0 +1,43 @@
+/// \file H_Kicker.h
+/// \brief Classes aiming at simulating kickers in LHC beamline.
+/// fk [rad] for kickers !!!!
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+#ifndef _H_Kicker_
+#define _H_Kicker_
+
+// local #includes
+#include "H_OpticalElement.h"
+
+/// Abstract class aiming at simulating kickers in LHC beamline.
+class H_Kicker : public H_OpticalElement {
+
+public:
+	/// Constructors and destructor
+	//@{
+		H_Kicker():H_OpticalElement() {}
+		H_Kicker(const int dtype, const double s, const double k, const double l):H_OpticalElement(dtype,s,k,l){}
+		H_Kicker(const string nameE, const int dtype, const double s, const double k, const double l):H_OpticalElement(nameE,dtype,s,k,l){}
+		virtual ~H_Kicker() {return;};
+	//@}
+	/// prints the kicker properties
+		virtual void printProperties() const;
+		virtual H_Kicker* clone() const = 0;
+		void init();
+
+ 	protected:
+		virtual void setTypeString() = 0;
+		virtual void setMatrix(const float, const float, const float) = 0;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_Marker.h
===================================================================
--- /trunk/Utilities/Hector/include/H_Marker.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_Marker.h	(revision 3)
@@ -0,0 +1,41 @@
+#ifndef _H_Marker_
+#define _H_Marker_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Marker.h
+/// \brief Class defining a marker in the beamline (e.g. for interaction point)
+
+// local includes
+#include "H_Drift.h"
+
+/// \brief Class defining a marker in the beamline (e.g. for interaction point)
+class H_Marker : public H_Drift {
+
+	public:
+	/// Constructors and destructor
+	//@{
+		H_Marker():H_Drift() { type = MARKER; init();}
+        	H_Marker(const double s):H_Drift(s,0.) { type =MARKER; init();}
+	        H_Marker(const string nameE, const double s):H_Drift(nameE,s,0.) { type=MARKER; init();}
+	        ~H_Marker() { return; };
+	//@}
+        	virtual void printProperties() const;
+		H_Marker* clone() const ;
+	        void init();
+
+	private:
+        	virtual void setTypeString() {typestring = MARKERNAME;};
+	        virtual void setMatrix(const float , const float, const float) ;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_OpticalElement.h
===================================================================
--- /trunk/Utilities/Hector/include/H_OpticalElement.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_OpticalElement.h	(revision 3)
@@ -0,0 +1,219 @@
+#ifndef _H_OpticalElement_
+#define _H_OpticalElement_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_OpticalElement.h
+/// \brief Class aiming at describing any beam optical element.
+///
+/// This is an abstract base class
+/// subclass must define setTypeString() and setMatrix() methods.
+/// Quadrupole, Dipole, Kickers and Drift inherit from this class.
+
+// c++ #includes
+#include <iostream>
+#include <string>
+
+// ROOT #includes
+#include "TMatrix.h"
+#include "TVectorD.h"
+
+// local #includes
+#include "H_TransportMatrices.h"
+#include "H_Parameters.h"
+#include "H_Aperture.h"
+
+using namespace std;
+
+	// type #defines
+#define DRIFT        1
+#define RDIPOLE      2
+#define SDIPOLE      3
+#define VQUADRUPOLE  4
+#define HQUADRUPOLE  5
+#define VKICKER      6
+#define HKICKER      7
+#define RCOLLIMATOR  8
+#define ECOLLIMATOR  9
+#define CCOLLIMATOR 10
+#define RP          11
+#define IP          12
+#define MARKER      13
+
+	// typestring[30] #defines
+#define DRIFTNAME	"Drift        "
+#define RDIPOLENAME	"R-Dipole     "
+#define SDIPOLENAME	"S-Dipole     "
+#define VQUADRUPOLENAME	"V-Quadrupole "
+#define HQUADRUPOLENAME	"H-Quadrupole "
+#define VKICKERNAME     "V-Kicker     "
+#define HKICKERNAME     "H-Kicker     "
+#define RCOLLIMATORNAME "R-Collimator "
+#define ECOLLIMATORNAME "E-Collimator "
+#define CCOLLIMATORNAME "C-Collimator "
+#define RPNAME          "Roman Pot    "
+#define IPNAME          "IP           "
+#define MARKERNAME      "Marker       "
+
+/// Describes any beam optical element.
+class H_OpticalElement {
+
+	public:
+        ///     init method for constructors
+                void init(const string, const int , const double , const double , const double);
+		/// Constructors and destructor
+		//@{
+		H_OpticalElement(const string, const int, const double, const double, const double, H_Aperture*);
+		H_OpticalElement(const int, const double, const double, const double, H_Aperture*);
+		H_OpticalElement(const string, const int, const double, const double, const double);
+		H_OpticalElement(const int, const double, const double, const double);
+		H_OpticalElement();
+		H_OpticalElement(const H_OpticalElement&);
+		virtual ~H_OpticalElement() { delete element_aperture;};
+		//@}
+		///     Prints the element features
+	        virtual void printProperties() const ;
+		///     Shows the element transport matrix
+	        void showMatrix() const ;
+		///     Draws the aperture shape
+	        void drawAperture() const ;
+		///     Sets the aperture of the element
+		void setAperture(const H_Aperture*);
+		///     Ordering operator acting on the s coordinate
+		inline bool operator>(const H_OpticalElement tocomp) const {if(fs>tocomp.getS()) { return true; } else { return false; }};
+		///     Ordering operator acting on the s coordinate
+		inline bool operator<(const H_OpticalElement tocomp) const {if(fs<tocomp.getS()) { return true; } else { return false; }};
+		/// 	Copy operator
+		H_OpticalElement& operator=(const H_OpticalElement&); 
+		///     Sets the element longitudinal (s), and horizontal (x) and vertical (y) coordinates.
+		//@{
+		inline void setS(const double new_s) {fs=new_s;};
+		inline void setLength(const double new_l) { element_length = new_l;};
+		inline void setX(const double new_pos) {
+		        /// @param new_pos in [m]
+	        	element_aperture->setPosition(new_pos*URAD,ypos);
+		        xpos = new_pos;
+		};
+		inline void setY(const double new_pos) {
+		        /// @param new_pos in [m]
+		        element_aperture->setPosition(xpos,new_pos*URAD);
+		        ypos = new_pos;
+		};
+		inline void setTX(const double new_ang) {
+			txpos = new_ang;
+		};
+		inline void setTY(const double new_ang) {
+			typos = new_ang;
+		}
+		//@}
+		///     Returns the element longitudinal (s), horizontal (x) and vertical (y) coordinates, and corresponding angles.
+		//@{
+	        inline double getS() const {return fs;};
+		inline double getX() const {return xpos;};
+		inline double getY() const {return ypos;};
+		inline double getTX() const {return txpos;};
+		inline double getTY() const {return typos;};
+		//@}
+		///     Returns the element length
+	        inline double getLength() const { return element_length; };
+		///     Returns the element magnetic strength
+	        inline double getK() const { return fk; };
+		///     Returns the element type, as (int)  or (string)
+		//@{
+	        inline int getType() const { return type; };
+		inline const string getTypeString() const { return typestring; };
+		//@}
+		///     Returns the element (string) name
+		inline const string getName() const { return name; };
+		///     Draws the element from min to max in the current pad
+		void draw(const float, const float) const;
+		///     Checks if the (x,y) coordinates are within the aperture acceptance
+		inline bool isInside(const double x, const double y) const { return (bool) element_aperture->isInside(x,y);};
+		///     Returns the element transport matrix
+		//@{
+		TMatrix getMatrix() ;
+		TMatrix getMatrix(const float, const float, const float) ;
+		//@}
+		///     Returns the element aperture
+		H_Aperture* getAperture() const {return element_aperture;};
+		///	Sets the beta functions
+		//@{
+		inline void setBetaX(const double beta) { betax = beta;};
+		inline void setBetaY(const double beta) { betay = beta;};
+		//@}
+		///	Returns the beta functions
+		//@{
+		inline double getBetaX() const {return betax;};
+		inline double getBetaY() const {return betay;};
+		//@}
+                ///     Sets the dispersion functions
+                //@{
+                inline void setDX(const double disp) { dx = disp;};
+                inline void setDY(const double disp) { dy = disp;};
+                //@}
+                ///     Returns the dispersion functions
+                //@{
+                inline double getDX() const {return dx;};
+                inline double getDY() const {return dy;};
+                //@}
+                //@}
+                ///     Sets the relative position functions (from MAD), relative to the beamline reference frame
+                //@{
+                inline void setRelX(const double rel_x) { relx = rel_x;};
+                inline void setRelY(const double rel_y) { rely = rel_y;};
+                //@}
+                ///     Returns the position functions (from MAD), relative to the beamline reference frame
+                //@{
+                inline double getRelX() const {return relx;};
+                inline double getRelY() const {return rely;};
+                //@}
+		virtual H_OpticalElement* clone() const { return new H_OpticalElement();};
+		TVectorD getHitPosition(TVectorD, double, double, double);
+
+
+	protected:
+		/// Optical element coordinates : fs [m], xpos [m], ypos [m], txpos [rad], typos [rad].
+		//@{
+        	double fs, xpos, ypos, txpos, typos;
+		//@}
+		/// Optical element lenght.
+		double element_length;
+		/// Magnetic field strength.
+		double fk;
+		/// Beam \f$ \beta \f$ functions.
+		//@{
+		double betax, betay;
+		//@}
+		/// Beam dispersion in position 
+		//@{
+		double dx, dy;
+		//@}
+		/// Beam position, relative to the beam ideal path, from MAD
+		//@{
+		double relx, rely;
+		//@}
+		/// Optical element type (Dipole, drift, etc).
+     		int type;
+		/// Optical element name and type.
+		//@{
+		string name, typestring;
+		//@}
+		virtual void setTypeString() {return;};
+		/// Optical element transport matrix.
+	    virtual void setMatrix(const float, const float, const float) { cout<<"dummy setmatrix"<<endl; return;};
+		/// Optical element transport matrix.
+ 		TMatrix element_mat;
+		/// Optical element aperture. 
+	    	H_Aperture* element_aperture;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_Parameters.h
===================================================================
--- /trunk/Utilities/Hector/include/H_Parameters.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_Parameters.h	(revision 3)
@@ -0,0 +1,91 @@
+#ifndef _Hector_parameters_
+#define _Hector_parameters_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+	J.~de Favereau, X.~Rouby and K.~Piotrzkowski, 
+        Hector, a fast simulator for the transport of particles in beamlines,
+	JINST 2, P09005 (2007)
+	arXiv:0707.1198 [physics.acc-ph]
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Parameters.h
+/// \brief Class aiming at gathering all parameters that must be defined.
+///
+/// Units : angles [\f$ \mu \f$rad], distances [\f$ \mu \f$m], energies [GeV], c=[1].
+
+#include <cmath>
+
+/* from physics and maths */
+   /// proton mass [GeV]
+const double MP=0.93827;
+   /// proton charge [e]
+const double QP=1.;
+   /// pi
+#ifndef __PI__ 
+#define __PI__
+const double PI=acos(-1.); 
+#endif
+   /// conversion factor for \f$\mu\f$rad <-> rad
+const double URAD=1000000.;
+
+/* beam parameters */
+   /// beam nominal energy in GeV
+const double BE=7000.;
+   /// beam energy divergence, in GeV
+const double SBE=0.79;
+   /// beam nominal energy in TeV
+const double BETEV=7.;
+   /// beam S @ IP
+const double PS=0.;
+   /// beam X @ IP
+const double PX=-500.;    
+   /// beam Y @ IP
+const double PY=0.;
+   /// beam longitudinal dispersion
+const double SS=0.;
+   /// beam lateral width SX @ IP
+const double SX=16.63;
+   /// beam lateral width SY @ IP
+const double SY=16.63;
+   /// beam transverse direction angle TX @ IP
+const double TX=0.;
+   /// beam transverse direction angle TY @ IP
+const double TY=0.;
+   /// beam angular divergence STX @ IP
+const double STX=30.23;
+   /// beam angular divergence STY @ IP
+const double STY=30.23;
+	/// half crossing angle at IP [\f$ \mu \f$RAD]
+const double CRANG=142.5;
+
+// local defines, used in H_BeamParticle & H_OpticalElements
+#define LENGTH_VEC 5
+#define INDEX_X 0
+#define INDEX_TX 1
+#define INDEX_Y 2
+#define INDEX_TY 3
+#define INDEX_S 4
+// (x,theta_x,y,theta_y,s)
+//
+
+/// include Pythia libraries ? (not included on some ROOT installations)
+//#define _include_pythia_
+
+const unsigned int TM = 0; // not used anymore. left for backward compatibility
+const unsigned int AM = 1; // not used anymore. left for backward compatibility
+
+
+/* display parameters */
+   /// Verbose mode ?
+const bool VERBOSE=false; 
+
+#endif
+
Index: /trunk/Utilities/Hector/include/H_Quadrupole.h
===================================================================
--- /trunk/Utilities/Hector/include/H_Quadrupole.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_Quadrupole.h	(revision 3)
@@ -0,0 +1,42 @@
+#ifndef _H_Quadrupole_
+#define _H_Quadrupole_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Quadrupole.h
+/// \brief Class describing quadrupoles.
+
+// local #includes
+#include "H_OpticalElement.h"
+
+/// Abstract class aiming at simulating LHC beam quadrupoles.
+class H_Quadrupole : public H_OpticalElement {
+
+	public:
+	///     Constructors and destructor
+	//@{
+		H_Quadrupole():H_OpticalElement() {}
+		H_Quadrupole(const int dtype, const double s, const double k, const double l) : H_OpticalElement(dtype,s,k,l) {}
+		H_Quadrupole(const string nameE, const int dtype, const double s, const double k, const double l) : H_OpticalElement(nameE,dtype,s,k,l) {}
+		virtual ~H_Quadrupole() {return;};
+	//@}	
+		virtual void printProperties() const;
+		virtual H_Quadrupole* clone() const =0 ;
+		void init();
+
+ 	protected:
+		virtual void setTypeString() =0;
+		virtual void setMatrix(const float, const float, const float) = 0;
+	   	
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_RecRPObject.h
===================================================================
--- /trunk/Utilities/Hector/include/H_RecRPObject.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_RecRPObject.h	(revision 3)
@@ -0,0 +1,68 @@
+#ifndef _H_RecRPObject_
+#define _H_RecRPObject_
+
+/*
+ * ---- Hector the simulator ----
+ * A fast simulator of particles through generic beamlines.
+ * J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+ *
+ * http://www.fynu.ucl.ac.be/hector.html
+ *
+ * Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+ * UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_RecRPObject.h
+/// \brief Reconstructed information from objects detected by two roman pots
+
+#include "TF1.h"
+
+#include "H_BeamLine.h"
+
+#define NOT_YET_COMPUTED -666
+
+class H_RecRPObject {
+	public:
+		H_RecRPObject();
+		H_RecRPObject(const float, const float, H_AbstractBeamLine* );
+		H_RecRPObject(const H_RecRPObject&);
+		H_RecRPObject& operator=(const H_RecRPObject&);
+		~H_RecRPObject() {if(f_1) delete f_1; if(f_2) delete f_2; if(g_1) delete g_1; if(g_2) delete g_2; if(d_1) delete d_1; if(d_2) delete d_2; if(k_1) delete k_1; if(k_2) delete k_2; if(l_1) delete l_1; if(l_2) delete l_2; };
+
+		inline float getX1() const {return x1;};
+		inline float getX2() const {return x2;};
+		inline float getY1() const {return y1;};
+		inline float getY2() const {return y2;};
+		inline float getS1() const {return s1;};
+		inline float getS2() const {return s2;};
+
+		float getTX();
+		float getTY();
+		float getE();
+		float getE(int );
+		float getQ2();
+		float getPt();
+
+		void setPositions(const float, const float, const float, const float);
+		void setPosition_det1(const float, const float);
+		void setPosition_det2(const float, const float);
+		void setDetPos(const float, const float);
+		void setERange(const float, const float);
+		void computeERange();
+		void initialize();
+		void computeAll();
+
+	protected:
+
+		float emin, emax;
+		float x1, x2, y1, y2, s1, s2;
+		float txip, tyip, energy, q2, pt;
+		H_AbstractBeamLine* thebeam;
+		TF1* f_1, *f_2;
+		TF1* g_1, *g_2;
+		TF1* d_1, *d_2;
+		TF1* k_1, *k_2;
+		TF1* l_1, *l_2;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_RectEllipticAperture.h
===================================================================
--- /trunk/Utilities/Hector/include/H_RectEllipticAperture.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_RectEllipticAperture.h	(revision 3)
@@ -0,0 +1,39 @@
+#ifndef _H_RectEllipticAperture_
+#define _H_RectEllipticAperture_
+
+/// \file H_RectEllipticAperture.h
+/// \brief Defines the Rect-Elliptic aperture of beamline elements.
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+// local #includes
+#include "H_Aperture.h"
+
+/// Rect-ellipse apertures
+class H_RectEllipticAperture: public H_Aperture {
+
+	public:
+		///     Constructors and Destructor
+		//@{
+		H_RectEllipticAperture():H_Aperture(RECTELLIPSE,0,0,0,0,0,0) {}
+		H_RectEllipticAperture(const float,const float,const float,const float, const float, const float);
+		~H_RectEllipticAperture() {return;};
+		H_RectEllipticAperture* clone() const;
+		//@}
+		virtual void printProperties() const;
+		/// Checks whether the point is inside the aperture or not
+		virtual bool isInside(const float, const float) const;
+		/// Draws the aperture shape.
+		virtual void draw(const float scale=1) const;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_RectangularAperture.h
===================================================================
--- /trunk/Utilities/Hector/include/H_RectangularAperture.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_RectangularAperture.h	(revision 3)
@@ -0,0 +1,39 @@
+#ifndef _H_RectangularAperture_
+#define _H_RectangularAperture_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_RectangularAperture.h
+/// \brief Defines the rectangular aperture of beamline elements.
+
+// local #includes
+#include "H_Aperture.h"
+
+/// Rectangular apertures
+class H_RectangularAperture : public H_Aperture {
+
+	public:
+		/// Constructors and destructor
+		//@{
+		H_RectangularAperture():H_Aperture(RECTANGULAR,0,0,0,0,0,0) {}
+		H_RectangularAperture(const float,const float,const float,const float);
+		~H_RectangularAperture() {return;};
+		H_RectangularAperture* clone() const;
+		//@}
+		/// Checks whether the point is inside the aperture or not 
+		virtual bool isInside(const float, const float) const;
+		/// Draws the aperture shape.
+		virtual void draw(const float scale=1) const;
+		virtual void printProperties() const;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_RectangularCollimator.h
===================================================================
--- /trunk/Utilities/Hector/include/H_RectangularCollimator.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_RectangularCollimator.h	(revision 3)
@@ -0,0 +1,41 @@
+#ifndef _H_RectangularCollimator_
+#define _H_RectangularCollimator_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_RectangularCollimator.h
+/// \brief Class describing Rectangular Collimators
+
+// local #includes
+#include "H_Drift.h"
+
+/// R-Collimators for the LHC beamline.
+class H_RectangularCollimator : public H_Drift {
+
+	public:
+	/// Constructors and destructor
+	//@{
+		H_RectangularCollimator():H_Drift() {type = RCOLLIMATOR; init();}
+		H_RectangularCollimator(const double, const double );
+		H_RectangularCollimator(const string, const double, const double );
+		~H_RectangularCollimator() { return; };
+	//@}
+		virtual void printProperties() const;
+		H_RectangularCollimator* clone() const;
+		void init();
+	private:
+	 	virtual void setTypeString() {typestring=RCOLLIMATORNAME;};
+		virtual void setMatrix(const float, const float, const float) ;
+
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_RectangularDipole.h
===================================================================
--- /trunk/Utilities/Hector/include/H_RectangularDipole.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_RectangularDipole.h	(revision 3)
@@ -0,0 +1,37 @@
+#ifndef _H_RectangularDipole_
+#define _H_RectangularDipole_
+
+/// \file H_RectangularDipole.h
+/// \brief Classes aiming at simulating LHC beam rectangular dipoles.
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+#include "H_Dipole.h"
+
+/// Rectangle dipoles.
+class H_RectangularDipole : public H_Dipole {
+
+	public:
+		/// constructor
+		//@{
+		H_RectangularDipole():H_Dipole(RDIPOLE,0.,0.,0.) {init();}
+		H_RectangularDipole(const double s, const double k, const double l) :H_Dipole(RDIPOLE,s,k,l){init();}
+		H_RectangularDipole(const string nameE, const double s, const double k, const double l) :H_Dipole(nameE,RDIPOLE,s,k,l){init();}
+		~H_RectangularDipole() { return; };
+		//@}
+		H_RectangularDipole* clone() const ;
+	private:
+		virtual void setTypeString() { typestring = RDIPOLENAME;};
+		virtual void setMatrix(const float, const float, const float) ;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_RomanPot.h
===================================================================
--- /trunk/Utilities/Hector/include/H_RomanPot.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_RomanPot.h	(revision 3)
@@ -0,0 +1,43 @@
+#ifndef _H_RomanPot_
+#define _H_RomanPot_
+
+/// \file H_RomanPot.h
+/// \brief Roman pot class
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+// local #includes
+#include "H_Drift.h"
+
+#define RP_LENGTH 0.0001
+#define RP_HEIGHT 10000
+/// Roman pot as an optics element.
+class H_RomanPot : public H_Drift {
+
+	public:
+	///     Constructors and destructor
+	//@{
+		H_RomanPot():H_Drift() {type = RP; init();}
+		H_RomanPot(const string, const double, const double);
+		H_RomanPot(const double, const double);
+		~H_RomanPot() { return; };
+	//@}
+		virtual void printProperties() const;
+		H_RomanPot* clone() const ;
+		void init();
+	private:
+		virtual void setTypeString() {typestring=RPNAME;};
+		virtual void setMatrix(const float, const float, const float) ;
+
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_SectorDipole.h
===================================================================
--- /trunk/Utilities/Hector/include/H_SectorDipole.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_SectorDipole.h	(revision 3)
@@ -0,0 +1,37 @@
+/// \file H_SectorDipole.h
+/// \brief Classes aiming at simulating sector dipoles.
+
+#ifndef _H_SectorDipole_
+#define _H_SectorDipole_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+#include "H_Dipole.h"
+
+/// Sector dipoles.
+class H_SectorDipole : public H_Dipole {
+
+	public:
+		/// Constructors and destructor
+		//@{
+		H_SectorDipole():H_Dipole(SDIPOLE,0.,0.,0.) {init();}
+		H_SectorDipole(const double s, const double k, const double l) :H_Dipole(SDIPOLE,s,k,l){init();}
+		H_SectorDipole(const string nameE, const double s, const double k, const double l) :H_Dipole(nameE,SDIPOLE,s,k,l){init();}
+		~H_SectorDipole() {return;};
+		//@}
+		H_SectorDipole* clone() const ;
+	private:
+		virtual void setTypeString() { typestring = SDIPOLENAME;};
+		virtual void setMatrix(const float ,const float, const float) ;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_TransportMatrices.h
===================================================================
--- /trunk/Utilities/Hector/include/H_TransportMatrices.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_TransportMatrices.h	(revision 3)
@@ -0,0 +1,212 @@
+#ifndef _H_TransportMatrices_
+#define _H_TransportMatrices_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/** \file H_TransportMatrices.h
+ * \brief Contains the matrices defining the propagation of the beam.
+ * 
+ * The matrices should have the following units :
+ *	\f$
+ *	\mathbf{M} =
+ *	\left(
+ *	\begin{array}{cccccc}
+ *	    1 & 1/m & 1 & 1/m & GeV/m & 1 \\
+ *	    m & 1 & m & 1 & GeV & 1 \\
+ *	    1 & 1/m & 1 & 1/m & GeV/m & 1\\
+ *	    m & 1 & m & 1 & GeV & 1 \\
+ *	  m/GeV & 1/GeV & m/GeV & 1/GeV & 1 & 1\\
+ *	    1 & 1 & 1 & 1 & 1  & 1 \\	
+ *	\end{array}
+ *	\right)
+ *	\f$
+ *
+ *	Note : convention is transposed compared to ref : x0.M = x1
+ * 	instead of x1 = M.x0 so the matrices should be transposed.
+ */
+
+// ROOT #includes
+#include "TMatrix.h"
+using namespace std;
+
+	/// transport matrix dimension
+#define MDIM 6
+
+/// \f$ \omega(k,l) = l \sqrt{|k|} \f$ is needed for the quadrupole matrices
+extern double omega(const double , const double );
+
+/// \f$ r(k) \f$ is needed for the dipole matrices
+extern double radius(const double );
+
+/// Prints the matrix
+extern void printMatrix(TMatrix);
+
+/// \brief Returns the matrix for a vertically focussing quadrupole (H_VerticalQuadrupole)
+
+/*! \f$
+ \mathbf{M} =
+ \left(
+ \begin{array}{cccccc}
+ \cosh(\omega) & \sqrt{k}\sinh(\omega) & 0 & 0 & 0 & 0\\
+ (1/\sqrt{k})sinh(\omega) & \cosh(\omega) & 0 & 0 & 0 &0\\
+ 0 & 0 & \cos(\omega) & -\sqrt{k}sin(\omega) & 0 &0\\
+ 0 & 0 & (1/\sqrt{k})*sin(\omega) & \cos(\omega) & 0 &0\\
+ 0 & 0 & 0 & 0 & 1 &0\\
+ 0 & 0 & 0 & 0 & 0 &1 \\
+ \end{array}
+ \right)
+ \f$
+
+ assuming \f$ k =  k_{0} \times \frac{p_{0}}{p_{0} - dp} \times \frac{q_{particle}}{q_{proton}} \f$ and \f$ \omega(k,l) = l \sqrt{|k|} \f$
+*/
+
+extern TMatrix vquadmat(const float , const float , const float , const float , const float);
+
+/// \brief Returns the matrix for a horizontally focussing quadrupole (H_HorizontalQuadrupole)
+
+/*! \f$
+ \mathbf{M} =
+ \left(
+ \begin{array}{cccccc}
+ \cos(\omega) & -\sqrt{k}\sin(\omega) & 0 & 0 & 0 & 0\\
+ (1/\sqrt{k})sin(\omega) & \cos(\omega) & 0 & 0 & 0 & 0\\
+ 0 & 0 & \cosh(\omega) & \sqrt{k}sinh(\omega) & 0 & 0\\
+ 0 & 0 & (1/\sqrt{k})sinh(\omega) & \cosh(\omega) & 0 & 0\\
+ 0 & 0 & 0 & 0 & 1 & 0\\
+ 0 & 0 & 0 & 0 & 0 & 1 \\
+ \end{array}
+ \right)
+ \f$
+
+ assuming \f$ k =  k_{0} \times \frac{p_{0}}{p_{0} - dp} \times \frac{q_{particle}}{q_{proton}} \f$ and \f$ \omega(k,l) = l \sqrt{|k|} \f$
+*/
+extern TMatrix hquadmat(const float , const float , const float , const float , const float);
+
+/// \brief Returns the matrix for a rectangle dipole (H_RectangularDipole)
+
+/*! \f$
+ \mathbf{M} =
+ \left(
+ \begin{array}{cccccc}
+ \cos(l/r) & \frac{-1}{r} \sin(l/r) & 0 & 0 & 0 & 0\\
+ r \sin(l/r) & \cos(l/r) & 0 & 0 & 0 & 0\\
+ 0 & 0 & 1 & 0 & 0 &0\\
+ 0 & 0 & l & 1 & 0 &0\\
+ 2r \sin^2(l/2r)/BE & \sin(l/r)/BE & 0 & 0 & 1 &0\\
+ 0 & 0 & 0 & 0 & 0 & 1\\
+ \end{array}
+ \right)
+ \f$
+
+ assuming \f$ 1/r = k =  k_{0} \times \frac{p_{0}}{p_{0} - dp} \times \frac{q_{particle}}{q_{proton}} \f$ and \f$ BE = 7000 GeV \f$.
+
+Attention : numerical sensitivity with \f$ r*(1-\cos(l/r))/BE\f$. \\
+Using \f$ 2\sin^2(x/2) = 1-\cos(x)\f$ instead (see the variable called "simp")
+*/
+extern TMatrix rdipmat(const float, const float , const float , const float , const float);
+
+/// \brief Returns the matrix for a sector dipole (H_SectorDipole)
+
+/*! The matrix is different if the bending is on or off.
+ 
+ \f$
+ \mathbf{M_{bending-off}} =
+ \left(
+ \begin{array}{cccccc}
+ \cos(l/r) & \frac{-1}{r} \sin(l/r) & 0 & 0 & 0 & 0\\
+ r \sin(l/r) & \cos(l/r) & 0 & 0 & 0 & 0\\
+ 0 & 0 & 1 & 0 & 0 & 0\\
+ 0 & 0 & l & 1 & 0 & 0\\
+ 0 & 0 & 0 & 0 & 1 & 0\\
+ 0 & 0 & 0 & 0 & 0 & 1\\
+ \end{array}
+ \right)
+ \f$
+
+ \f$
+ \mathbf{M_{bending-on}} =
+ \left( 
+ \begin{array}{cccccc} 
+ \cos(l/r) & \frac{-1}{r} \sin(l/r) & 0 & 0 & 0 & 0\\
+ r \sin(l/r) & \cos(l/r) & 0 & 0 & 0 & 0\\
+ 0 & 0 & 1 & 0 & 0 &0\\ 
+ 0 & 0 & l & 1 & 0 &0\\ 
+ 2r \sin^2(l/2r)/BE & \sin(l/r)/BE & 0 & 0 & 1 & 0\\ 
+ 0 & 0 & 0 & 0 & 0 & 1\\
+ \end{array} 
+ \right) 
+ \f$ 
+ 
+ assuming \f$ 1/r = k =  k_{0} \times \frac{p_{0}}{p_{0} - dp} \times \frac{q_{particle}}{q_{proton}} \f$
+
+*/
+extern TMatrix sdipmat(const float, const float , const float , const float , const float );
+
+/// \brief Returns the matrix for a drift (H_Drift)
+
+/*! \f$
+ \mathbf{M} =
+ \left(
+ \begin{array}{cccccc}
+ 1 & 0 & 0 & 0 & 0 & 0\\
+ l & 1 & 0 & 0 & 0 & 0\\
+ 0 & 0 & 1 & 0 & 0 & 0\\
+ 0 & 0 & l & 1 & 0 & 0\\
+ 0 & 0 & 0 & 0 & 1 & 0\\
+ 0 & 0 & 0 & 0 & 0 & 1\\
+ \end{array}
+ \right)
+ \f$
+*/
+extern TMatrix driftmat(const float );
+
+/// \brief Returns the matrix for a horizontal kicker (H_HorizontalKicker)
+/*! \f$
+ \mathbf{M} =
+ \left(
+ \begin{array}{cccccc}
+ 1 & 0 & 0 & 0 & 0 & 0\\
+ l & 1 & 0 & 0 & 0 & 0 \\
+ 0 & 0 & 1 & 0 & 0 & 0\\
+ 0 & 0 & l & 1 & 0 & 0\\
+ 0 & 0 & 0 & 0 & 1 & 0\\
+ l \tan(k) /2 & k & 0 & 0 & 0 & 1\\
+ \end{array}
+ \right) 
+ \f$
+ 
+ assuming \f$ k =  k_{0} \times \frac{p_{0}}{p_{0} - dp} \times \frac{q_{particle}}{q_{proton}} \f$
+*/
+extern TMatrix hkickmat(const float, const float , const float , const float, const float);
+
+/// \brief Returns the matrix for a vertical kicker (H_VerticalKicker)
+/*! \f$
+ \mathbf{M} =
+ \left(
+ \begin{array}{cccccc}
+ 1 & 0 & 0 & 0 & 0 & 0\\
+ l & 1 & 0 & 0 & 0 & 0 \\
+ 0 & 0 & 1 & 0 & 0 & 0\\
+ 0 & 0 & l & 1 & 0 & 0\\
+ 0 & 0 & 0 & 0 & 1 & 0\\
+ 0 & 0 & l \tan(k) /2 & k & 0 & 1\\
+ \end{array}
+ \right) 
+ \f$
+
+ assuming \f$ k =  k_{0} \times \frac{p_{0}}{p_{0} - dp} \times \frac{q_{particle}}{q_{proton}} \f$
+*/
+extern TMatrix vkickmat(const float, const float , const float , const float , const float);
+
+
+
+#endif
Index: /trunk/Utilities/Hector/include/H_VerticalKicker.h
===================================================================
--- /trunk/Utilities/Hector/include/H_VerticalKicker.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_VerticalKicker.h	(revision 3)
@@ -0,0 +1,41 @@
+#ifndef _H_VerticalKicker_
+#define _H_VerticalKicker_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_VerticalKicker.h
+/// \brief Classes aiming at simulating vertical kickers in the beamline.
+///
+/// fk [rad] for kickers !!!!
+
+
+// local #includes
+#include "H_Kicker.h"
+
+/// Vertical kickers for the beamline.
+class H_VerticalKicker : public H_Kicker {
+
+	public:
+	/// Constructors and destructor
+	//@{
+		H_VerticalKicker():H_Kicker(VKICKER,0.,0.,0.) {init();}
+		H_VerticalKicker(const double s, const double k, const double l) :H_Kicker(VKICKER,s,k,l){init();}
+		H_VerticalKicker(const string nameE, const double s, const double k, const double l) :H_Kicker(nameE,VKICKER,s,k,l){init();}
+		~H_VerticalKicker() {return;};
+	//@}
+		H_VerticalKicker* clone() const ;
+	private:
+		virtual void setTypeString() {typestring=VKICKERNAME;};
+		virtual void setMatrix(const float, const float, const float) ;
+};
+
+#endif
Index: /trunk/Utilities/Hector/include/H_VerticalQuadrupole.h
===================================================================
--- /trunk/Utilities/Hector/include/H_VerticalQuadrupole.h	(revision 3)
+++ /trunk/Utilities/Hector/include/H_VerticalQuadrupole.h	(revision 3)
@@ -0,0 +1,38 @@
+#ifndef _H_VerticalQuadrupole_
+#define _H_VerticalQuadrupole_
+
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_VerticalQuadrupole.h
+/// \brief Vertically focussing quadrupoles.
+
+// local #includes
+#include "H_Quadrupole.h"
+
+/// Vertically focussing quadrupoles.
+class H_VerticalQuadrupole : public H_Quadrupole {
+
+	public:
+	///     Constructors and destructor
+	//@{
+		H_VerticalQuadrupole():H_Quadrupole(VQUADRUPOLE,0.,0.,0.) {init();}
+		H_VerticalQuadrupole(const double s, const double k, const double l):H_Quadrupole(VQUADRUPOLE,s,k,l) {init();}
+		H_VerticalQuadrupole(string nameE, const double s, const double k, const double l):H_Quadrupole(nameE,VQUADRUPOLE,s,k,l) {init();}
+		~H_VerticalQuadrupole() {return;};
+	//@}
+		H_VerticalQuadrupole* clone() const ;
+	private:
+		virtual void setTypeString() {typestring = VQUADRUPOLENAME;} ;
+		virtual void setMatrix(const float, const float, const float) ;
+};
+
+#endif
Index: /trunk/Utilities/Hector/src/H_AbstractBeamLine.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_AbstractBeamLine.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_AbstractBeamLine.cc	(revision 3)
@@ -0,0 +1,645 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+
+/// \file H_AbstractBeamLine.cc
+/// \brief Class describing ideal beamline.
+///
+/// Units : angles [rad], distances [m], energies [GeV], c=[1].
+
+// c++ #includes
+#include <iostream>
+#include <cmath>
+
+// ROOT #includes
+#include "TPaveLabel.h"
+#include "TLine.h"
+#include "TGaxis.h"
+#include "TLegend.h"
+#include "TF1.h"
+#include "TROOT.h"
+
+// local #includes
+#include "H_Parameters.h"
+#include "H_TransportMatrices.h"
+#include "H_Drift.h"
+#include "H_AbstractBeamLine.h"
+#include "H_RomanPot.h"
+using namespace std;
+
+void H_AbstractBeamLine::init(const float length) {
+	beam_mat.ResizeTo(MDIM,MDIM);
+	beam_mat = driftmat(length);
+  	beam_length = length;
+	H_Drift * drift0 = new H_Drift("Drift0",0.,length);
+	add(drift0);
+	return;
+}
+
+H_AbstractBeamLine::H_AbstractBeamLine(const H_AbstractBeamLine& beamline) {
+	elements = beamline.elements;
+	matrices = beamline.matrices;
+	beam_mat.ResizeTo(MDIM,MDIM);
+	beam_mat = beamline.beam_mat;
+	beam_length = beamline.beam_length;
+}
+
+H_AbstractBeamLine& H_AbstractBeamLine::operator=(const H_AbstractBeamLine& beamline) {
+	if(this== &beamline) return *this;
+        elements = beamline.elements;
+        matrices = beamline.matrices;
+        beam_mat = beamline.beam_mat;
+	beam_length = beamline.beam_length;
+	return *this;
+}
+
+H_AbstractBeamLine* H_AbstractBeamLine::clone() const {
+	H_AbstractBeamLine* temp_beam = new H_AbstractBeamLine(beam_length);
+	vector<H_OpticalElement*>::const_iterator element_i;
+	for (element_i = elements.begin(); element_i<elements.end(); element_i++) {
+		if((*element_i)->getType()!=DRIFT) {
+			H_OpticalElement* temp_el = (*element_i)->clone();
+			temp_beam->add(temp_el);
+		}
+	}
+	temp_beam->beam_mat = beam_mat;
+	temp_beam->matrices = matrices;
+	return temp_beam;
+}
+
+H_AbstractBeamLine::~H_AbstractBeamLine() {
+	vector<H_OpticalElement*>::iterator element_i;
+	for (element_i = elements.begin(); element_i<elements.end(); element_i++) {
+		delete (*element_i);
+	}
+	elements.clear(); 
+	matrices.clear(); 
+}
+
+void H_AbstractBeamLine::add(H_OpticalElement * newElement) {
+	/// @param newElement is added to the beamline
+//	H_OpticalElement * el = new H_OpticalElement(*newElement);
+//	H_OpticalElement * el = const_cast<H_OpticalElement*> newElement; 
+//	H_OpticalElement * el = newElement;
+	elements.push_back(newElement);
+ 	float a = newElement->getS()+newElement->getLength();
+	if (a > beam_length)	{
+		beam_length = a;
+		if(VERBOSE) cout<<"<H_AbstractBeamLine> WARNING : element ("<< newElement->getName()<<") too far away. The beam length has been extended to "<< beam_length << ". "<<endl;
+	}
+	calcSequence();
+	calcMatrix();
+}
+
+void H_AbstractBeamLine::add(H_OpticalElement & newElement) {
+	/// @param newElement is added to the beamline
+//	H_OpticalElement * el = new H_OpticalElement(newElement);
+//	elements.push_back(el);
+	elements.push_back(&newElement);
+ 	float a = newElement.getS()+newElement.getLength();
+	if (a > beam_length)	{
+		beam_length = a;
+		if(VERBOSE) cout<<"<H_AbstractBeamLine> WARNING : element ("<< newElement.getName()<<") too far away. The beam length has been extended to "<< beam_length << ". "<<endl;
+	}
+	calcSequence();
+	calcMatrix();
+}
+
+const TMatrix H_AbstractBeamLine::getBeamMatrix() const {
+	return beam_mat;
+}
+
+const TMatrix H_AbstractBeamLine::getBeamMatrix(const float eloss,const float p_mass, const float p_charge) {
+
+	vector<H_OpticalElement*>::iterator element_i;
+    TMatrix calc_mat(MDIM,MDIM);
+
+    // initialization
+	calc_mat.UnitMatrix();
+	
+	// multiplies the matrix of each beam's element
+	// and add each product matrix to the list of matrices.
+	for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+		calc_mat *= (*element_i)->getMatrix(eloss,p_mass,p_charge);
+	}
+	return calc_mat;
+}
+
+const TMatrix H_AbstractBeamLine::getPartialMatrix(const string elname, const float eloss, const float p_mass, const float p_charge) {
+
+	vector<H_OpticalElement*>::iterator element_i;
+	TMatrix calc_mat(MDIM,MDIM);
+
+	calc_mat.UnitMatrix();
+
+	for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+		calc_mat *= (*element_i)->getMatrix(eloss,p_mass,p_charge);
+		if(elname==(*element_i)->getName()) {
+			return calc_mat;
+		}
+	}
+	cout<<"<H_AbstractBeamLine> Element "<<elname<<" desn't exist. Returning full beam matrix"<<endl;
+	return calc_mat;
+}
+
+const TMatrix H_AbstractBeamLine::getPartialMatrix(const unsigned int element_position) const {
+ 	//const int N = (element_position<0)?0:(( (element_position)>elements.size()-1)?elements.size()-1:element_position);
+	const int N = (element_position>elements.size()-1)?elements.size()-1:element_position;
+	return *(matrices.begin()+N); // //for optimization of the code :same as return &matrices[N];
+}
+
+const TMatrix H_AbstractBeamLine::getPartialMatrix(const H_OpticalElement * element) const{
+	// returns the transport matrix to transport until the end of the specified element
+	// !!! 2 elements should never have the same name in "elements" !!!
+
+	vector<H_OpticalElement*>::const_iterator element_i;
+	vector<TMatrix>::const_iterator matrix_i;
+	TMatrix calc_mat(MDIM,MDIM);
+
+	// parses the list of optical elements and find the searched one
+	for(element_i = elements.begin(),matrix_i = matrices.begin(); element_i < elements.end(); element_i++, matrix_i++) {
+		if(element->getName() == (*element_i)->getName()) {
+			// element has been found
+			calc_mat = *matrix_i;
+        	}
+	}
+	return calc_mat;
+}
+
+H_OpticalElement * H_AbstractBeamLine::getElement(const unsigned int element_position) {
+	const unsigned int N = (element_position>elements.size())?elements.size():element_position;
+	return *(elements.begin()+N);//for optimization of the code :same as return &elements[N];
+}
+
+H_OpticalElement * H_AbstractBeamLine::getElement(const unsigned int element_position) const {
+	const unsigned int N = (element_position>elements.size())?elements.size():element_position;
+        return *(elements.begin()+N);//for optimization of the code :same as return &elements[N];
+}
+
+
+H_OpticalElement * H_AbstractBeamLine::getElement(const string el_name) {
+	for(unsigned int i=0; i < elements.size(); i++) {
+		if( (*(elements.begin()+i))->getName() == el_name ) 
+			return *(elements.begin()+i);
+	} // if found -> return ; else : not found at all !	
+	cout<<"<H_AbstractBeamLine> Element "<<el_name<<" not found"<<endl;
+	return *(elements.begin()+1);
+}
+
+H_OpticalElement * H_AbstractBeamLine::getElement(const string el_name) const {
+        for(unsigned int i=0; i < elements.size(); i++) {
+		if( (*(elements.begin()+i))->getName() == el_name)
+			return *(elements.begin()+i);
+	} // if found -> return ; else : not found at all !
+	cout<<"<H_AbstractBeamLine> Element "<<el_name<<" not found"<<endl;
+	return *(elements.begin()+1);
+}
+
+void H_AbstractBeamLine::printProperties() const {
+	vector<H_OpticalElement*>::const_iterator element_i;
+	cout << "Pointeurs des elements du faisceau" << endl;
+	for (element_i = elements.begin(); element_i < elements.end(); element_i++) {
+		cout << (int)(element_i-elements.begin()) << "\t" << (*element_i)->getName() << "\t" << (*element_i)->getS() << endl;	
+	}
+	return;
+}
+
+void H_AbstractBeamLine::showElements() const{
+	vector<H_OpticalElement*>::const_iterator element_i;
+	for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+		(*element_i)->printProperties();
+	}
+	cout << "Beam length = " << beam_length << endl;
+	cout << "Number of elements (including drifts) = " << getNumberOfElements() << endl;
+	return;
+}
+
+void H_AbstractBeamLine::showElements(const int type_el) const{
+	vector<H_OpticalElement*>::const_iterator element_i;
+	for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+		if ((*element_i)->getType()==type_el)
+			(*element_i)->printProperties();
+	}
+	return;
+}
+
+void H_AbstractBeamLine::showMatrix() const {
+	cout << "Transport matrix for the whole beam : " << endl;
+	cout << "(x,x',...) = (x*,x'*,...) M " <<endl;
+  	printMatrix(beam_mat);
+	return;
+}
+
+void H_AbstractBeamLine::showMatrices() const{
+	// prints the list of all transport matrices, from the whole beam.
+
+	vector<TMatrix>::const_iterator matrix_i;
+	vector<H_OpticalElement*>::const_iterator element_i;
+	TMatrix temp(MDIM,MDIM);
+
+	for(matrix_i = matrices.begin(), element_i = elements.begin(); matrix_i < matrices.end(); matrix_i++, element_i++) {
+		temp = *matrix_i;
+		cout << "Matrix for transport until s=" << (*element_i)->getS() + (*element_i)->getLength() << "m (" << (*element_i)->getName() << "). " << endl;
+		printMatrix(temp);
+		cout << endl;
+	}
+	return ;
+}
+
+void H_AbstractBeamLine::calcSequence() {
+		// reorders the elements, computes the drifts;
+
+	vector<H_OpticalElement*> temp_elements;
+	vector<H_OpticalElement*>::iterator element_i;
+		// element_i is a pointer to elements[i]
+
+	if(elements.size()==1) { return; }
+
+	// getting rid of drifts before calculating
+	for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+		if((*element_i)->getType() == DRIFT) {delete (*element_i); elements.erase(element_i); }
+	}
+
+	// ordering the elements in position
+	sort(elements.begin(),elements.end(),ordering());
+	// inserting the drifts before the other elements
+	float current_pos = 0;
+	float drift_length=0;
+
+	for(element_i=elements.begin(); element_i < elements.end(); element_i++) {
+		drift_length = (*element_i)->getS() - current_pos;
+		if(drift_length>0) {
+  			H_Drift *dr = new H_Drift(current_pos,drift_length);
+			temp_elements.push_back(dr); 
+		}
+		temp_elements.push_back(*element_i);
+		current_pos = (*element_i)->getS() + (*element_i)->getLength();
+	}
+	
+	//adding the last drift
+	drift_length = beam_length - current_pos;
+	if (drift_length>0) {
+			H_Drift *dr = new H_Drift(current_pos,drift_length);
+			temp_elements.push_back(dr);
+	}
+	
+	// cleaning : avoid some memory leaks
+	elements.clear();
+
+	for(element_i=temp_elements.begin(); element_i < temp_elements.end(); element_i++) {
+		elements.push_back(*element_i);
+	}
+}
+
+void H_AbstractBeamLine::calcMatrix() {
+	// computes the transport matrix for the beam upto here...
+	vector<H_OpticalElement*>::iterator element_i;
+	TMatrix calc_mat(MDIM,MDIM);
+
+	// initialization
+	matrices.clear();
+	calc_mat.UnitMatrix();
+
+	// multiplies the matrix of each beam's element
+	// and add each product matrix to the list of matrices.
+	for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+		calc_mat *= (*element_i)->getMatrix();
+		matrices.push_back(calc_mat);
+  	}
+
+	beam_mat.ResizeTo(MDIM,MDIM);
+	beam_mat = calc_mat;
+	return;
+}
+
+float qh(float k) {
+        float beta = (log((float)10.0))/0.05;
+		// put (std::log((float)10.0)) instead of log(10) to avoid compilation errors
+        return 0.8*(1-exp(-beta*fabs(k)));
+}
+
+float dh(float k) {
+        float psi = (log((float)10.0))/0.002;
+		// put (std::log((float)10.0)) instead of log(10) to avoid compilation errors
+        return 0.8*(1-exp(-psi*fabs(k)));
+}
+
+void H_AbstractBeamLine::draw(const float xmin, const float ymin, const float xmax, const float ymax) const{
+	gROOT->SetStyle("Plain");
+	TLegend* leg = new TLegend(xmin,ymin,xmax,ymax,""); 
+	leg->SetBorderSize(1);
+	leg->SetFillColor(kWhite);
+	TBox* b1 = new TBox();
+	TBox* b2 = new TBox(0,0,10,10);
+	TBox* b3 = new TBox(0,0,0,0);
+	TBox* b4 = new TBox(0,0,0,0);
+	TBox* b5 = new TBox(0,0,0,0);
+	TBox* b6 = new TBox(0,0,0,0);
+	TBox* b7 = new TBox(0,0,0,0);
+	b1->SetFillColor(RDIPOLE);
+	b2->SetFillColor(SDIPOLE);
+	b3->SetFillColor(VQUADRUPOLE);
+	b4->SetFillColor(HQUADRUPOLE);
+	b5->SetFillColor(HKICKER);
+	b6->SetFillColor(VKICKER);
+	b7->SetFillColor(RCOLLIMATOR);
+	leg->AddEntry(b1,"R-Dipole");
+	leg->AddEntry(b2,"S-Dipole");
+	leg->AddEntry(b3,"V-Quadrupole");
+	leg->AddEntry(b4,"H-Quadrupole");
+	leg->AddEntry(b5,HKICKERNAME);
+	leg->AddEntry(b6,VKICKERNAME);
+	leg->AddEntry(b7,"RCollimator");
+	leg->Draw();
+/*	TLine* l1 = new TLine(0.05,0.5,0.95,0.5);
+	TLine* l2 = new TLine(0.1,0.1,0.1,0.9);
+	TLine* l3 = new TLine(0.9,0.1,0.9,0.9);
+	TPaveLabel* p1 = new TPaveLabel(0.05,0.5,0.1,0.6,"IP");
+	TPaveLabel* p2 = new TPaveLabel(0.9,0.5,0.95,0.6,"RP");
+	TGaxis* a1 = new TGaxis(0.1,0.1,0.9,0.1,0,beam_length);
+	a1->SetLabelSize(0.08);
+	p1->SetBorderSize(1);
+	p2->SetBorderSize(1);
+	p1->SetFillColor(0);
+	p2->SetFillColor(0);
+	l1->Draw();
+	l2->Draw();
+	l3->Draw();
+	p1->Draw();
+	p2->Draw();
+	float x1,x2,y1,y2;
+	vector<TPaveLabel*> boxes;
+	vector<H_OpticalElement*>::const_iterator element_i;
+	for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+		x1 = 0.1 + ((*element_i)->getS()/beam_length)*0.8;
+		x2 = x1 + ((*element_i)->getLength()/beam_length)*0.8;
+		if((*element_i)->getType()>5) {
+			y1 = 0.3;
+			y2 = 0.7;
+		}
+		else if((*element_i)->getType()>3) {
+			y1 = 0.5 - qh((*element_i)->getK()*(*element_i)->getLength())/2.;
+			y2 = 0.5 + qh((*element_i)->getK()*(*element_i)->getLength())/2.;
+		} else {
+			y1 = 0.5 - dh((*element_i)->getK()*(*element_i)->getLength())/2.;
+			y2 = 0.5 + dh((*element_i)->getK()*(*element_i)->getLength())/2.;
+		}
+		TPaveLabel* cur_box = new TPaveLabel(x1,y1,x2,y2,"");
+		cur_box->SetFillStyle(1);
+		cur_box->SetFillColor(((int)(*element_i)->getType()));
+		cur_box->SetBorderSize(1);
+		if((*element_i)->getType()!=DRIFT) boxes.push_back(cur_box);
+	}
+	vector<TPaveLabel*>::iterator box_i;
+	for(box_i = boxes.begin(); box_i < boxes.end(); box_i++) {
+		(*box_i)->Draw();
+	}
+	a1->Draw();
+*/	
+	return;
+}
+
+void H_AbstractBeamLine::drawX(const float a_min, const float a_max, const float scale) const{
+	/// @param a_min defines the size of the drawing
+	/// @param a_max defines the size of the drawing
+	/// @param scale allows to multiply the drawing, i.e. changing the units
+	const int N = getNumberOfElements();
+	for(int i=0;i<N;i++) {
+		float height = fabs(a_max);
+        	float meight = fabs(a_min);
+        	float size = (height>meight)?meight:height;
+		float middle = getElement(i)->getX()*URAD*scale;
+        	if(getElement(i)->getType()!=DRIFT) getElement(i)->draw(middle+size/2.,middle-size/2.);
+    	}
+}
+
+void H_AbstractBeamLine::drawY(const float a_min, const float a_max) const{
+        /// @param a_min defines the size of the drawing 
+        /// @param a_max defines the size of the drawing
+        const int N = getNumberOfElements();
+        for(int i=0;i<N;i++) {
+                float height = fabs(a_max);
+                float meight = fabs(a_min);
+                float size = (height>meight)?meight:height;
+                float middle = getElement(i)->getY()*URAD;
+                if(getElement(i)->getType()!=DRIFT) getElement(i)->draw(middle+size/2.,middle-size/2.);
+        }
+}
+
+void H_AbstractBeamLine::moveElement(const string name, const float new_s) {
+	/// @param name identifies the element to move
+	/// @param new_s is where to put it
+       vector<H_OpticalElement*>::iterator element_i;
+       for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+	       if(name==(*element_i)->getName()) { (*element_i)->setS(new_s); }
+       }
+
+       calcSequence();
+       calcMatrix();
+       return;
+}
+
+void H_AbstractBeamLine::alignElement(const string name, const float disp_x, const float disp_y) {
+	/// @param name identifies the element to move
+	/// @param disp_x identifies the displacement to add in x [\f$ \mu m \f$]
+	/// @param disp_y identifies the displacement to add in y [\f$ \mu m \f$]
+		vector<H_OpticalElement*>::iterator element_i;
+		for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+			if(name==(*element_i)->getName()) { 
+				(*element_i)->setX((*element_i)->getX()+disp_x);
+				(*element_i)->setY((*element_i)->getY()+disp_y);
+				return ;
+			}
+		}
+		cout<<"<H_AbstractBeamLine> WARNING : Element "<<name<<" not found."<<endl; 
+		return;
+}
+
+void H_AbstractBeamLine::tiltElement(const string name, const float ang_x, const float ang_y) {
+	/// @param name identifies the element to move
+	/// @param ang_x identifies the angle to add in x
+	/// @param ang_y identifies the angle to add in y
+		vector<H_OpticalElement*>::iterator element_i;
+		for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+			if(name==(*element_i)->getName()) {
+				(*element_i)->setTX((*element_i)->getTX()+ang_x);
+				(*element_i)->setTY((*element_i)->getTY()+ang_y);
+				return ;
+			}
+		}
+		cout<<"<H_AbstractBeamLine> WARNING : Element "<<name<<" not found."<<endl; 
+		return;
+}
+
+void H_AbstractBeamLine::offsetElements(const float start, const float offset) {
+	/// @param start After this s [m] coordinate, all elements will be offset.
+	/// @param offset In meters
+
+	extern int relative_energy;
+	if(!relative_energy) {
+		vector<H_OpticalElement*>::iterator element_i;
+   	     for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+			if((*element_i)->getS() > start ) {
+    	       (*element_i)->setX(offset);
+       	    }
+		}
+	}
+}
+
+TGraph * H_AbstractBeamLine::getBetaX() const{
+        const int N = elements.size();
+        float * s = new float[N], * b = new float[N], temp;
+	int i=0, n=N;
+
+	vector<H_OpticalElement*>::const_iterator element_i;
+	for(element_i = elements.begin(); element_i < elements.end(); element_i++) {	
+		temp=(*element_i)->getBetaX();	
+		if (temp !=0) {
+			b[i] = (*element_i)->getBetaX();
+			s[i] = (*element_i)->getS();
+			i++;
+			n=i;
+		}
+	}
+
+        TGraph * betax = new TGraph(n,s,b);
+        betax->SetLineColor(1);
+	betax->SetLineStyle(2);
+	delete [] s;
+	delete [] b;
+        return betax;
+}
+
+TGraph * H_AbstractBeamLine::getBetaY() const{
+        const int N = elements.size();
+        float * s = new float[N], * b = new float[N], temp;
+        int i=0, n=N;
+
+        vector<H_OpticalElement*>::const_iterator element_i;
+        for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+                temp=(*element_i)->getBetaY();
+                if (temp !=0) {
+                        b[i] = (*element_i)->getBetaY();
+                        s[i] = (*element_i)->getS();
+                        i++;
+                        n=i;
+                }
+        }
+
+        TGraph * betay = new TGraph(n,s,b);
+        betay->SetLineColor(2);
+        betay->SetLineStyle(2);
+	delete [] s;
+	delete [] b;
+        return betay;
+}
+
+TGraph * H_AbstractBeamLine::getDX() const{
+        const int N = elements.size();
+        float * s = new float[N], * d = new float[N], temp;
+        int i=0, n=N;
+
+        vector<H_OpticalElement*>::const_iterator element_i;
+        for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+                temp=(*element_i)->getDX();
+                if (temp !=0) {
+                        d[i] = (*element_i)->getDX();
+                        s[i] = (*element_i)->getS();
+                        i++;
+                        n=i;
+                }
+        }
+
+        TGraph * dispx = new TGraph(n,s,d);
+        dispx->SetLineColor(8);
+        dispx->SetLineStyle(2);
+        delete [] s;
+        delete [] d;
+        return dispx;
+}
+
+TGraph * H_AbstractBeamLine::getDY() const{
+        const int N = elements.size();
+        float * s = new float[N], * d = new float[N], temp;
+        int i=0, n=N;
+ 
+        vector<H_OpticalElement*>::const_iterator element_i;
+        for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+                temp=(*element_i)->getDY();
+                if (temp !=0) {
+                        d[i] = (*element_i)->getDY();
+                        s[i] = (*element_i)->getS();
+                        i++;
+                        n=i;
+                }
+        }
+ 
+        TGraph * dispy = new TGraph(n,s,d);
+        dispy->SetLineColor(kBlue);
+        dispy->SetLineStyle(2);
+        delete [] s;
+        delete [] d;
+        return dispy;
+}
+
+
+TGraph * H_AbstractBeamLine::getRelX() const{
+        const int N = elements.size();
+        float * s = new float[N], * r = new float[N], temp;
+        int i=0, n=N;
+
+        vector<H_OpticalElement*>::const_iterator element_i;
+        for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+                temp=(*element_i)->getRelX();
+		if((*element_i)->getType() != DRIFT) {
+			r[i] = (*element_i)->getRelX();
+			s[i] = (*element_i)->getS();
+			i++;
+			n=i;
+		}
+	}
+
+        TGraph * relx = new TGraph(n,s,r);
+        relx->SetLineColor(kBlack);
+	relx->SetMarkerStyle(kOpenSquare);
+	relx->SetMarkerSize(0.6);
+        relx->SetLineStyle(2);
+        delete [] s;
+        delete [] r;
+        return relx;
+}
+
+TGraph * H_AbstractBeamLine::getRelY() const{
+        const int N = elements.size();
+        float * s = new float[N], * r = new float[N], temp;
+        int i=0, n=N;
+
+        vector<H_OpticalElement*>::const_iterator element_i;
+        for(element_i = elements.begin(); element_i < elements.end(); element_i++) {
+                temp=(*element_i)->getRelY();
+                if((*element_i)->getType() != DRIFT) {
+                        r[i] = (*element_i)->getRelY();
+                        s[i] = (*element_i)->getS();
+                        i++;
+                        n=i;
+                }
+        }
+
+        TGraph * rely = new TGraph(n,s,r);
+        rely->SetLineColor(kRed);
+	rely->SetMarkerStyle(kOpenSquare);
+	rely->SetMarkerSize(0.6);
+        rely->SetLineStyle(2);
+        delete [] s;
+        delete [] r;
+        return rely;
+}
+
Index: /trunk/Utilities/Hector/src/H_Aperture.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_Aperture.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_Aperture.cc	(revision 3)
@@ -0,0 +1,101 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Aperture.cc
+/// \brief Classes aiming at simulating the aperture of the LHC beamline elements.
+
+// C++ #includes
+#include <iostream>
+
+// local #includes
+#include "H_Aperture.h"
+using namespace std;
+
+H_Aperture::H_Aperture() {
+        type = NONE;
+        setApertureString();
+        x1 = 0;
+        x2 = 0;
+        x3 = 0;
+        x4 = 0;
+        fx = 0;
+        fy = 0;
+}
+
+H_Aperture::H_Aperture(const int dtype, const float size1, const float size2, const float size3, const float size4, const float posx, const float posy) {
+    /// @param dtype defines the aperture shape
+        /// @param size1, size2, size3, size4 are the geometrical sizes (length/width or great/small radii) in m
+	/// @param posx, posy are the (x,y) coordinates of the center of the aperture [m]
+        type = dtype;
+        setApertureString();
+        x1 = size1;
+        x2 = size2;
+	x3 = size3;
+	x4 = size4;
+        fx = posx;
+        fy = posy;
+}
+
+H_Aperture::H_Aperture(const H_Aperture& ap) {
+        type = ap.type;
+	aptypestring = ap.aptypestring;
+        x1 = ap.x1;
+        x2 = ap.x2;
+        x3 = ap.x3;
+        x4 = ap.x4;
+        fx = ap.fx;
+        fy = ap.fy;
+}
+
+H_Aperture& H_Aperture::operator=(const H_Aperture& ap) {
+	if(this==&ap) return *this;
+	type = ap.type;
+	aptypestring = ap.aptypestring;
+	x1 = ap.x1;
+	x2 = ap.x2;
+	x3 = ap.x3;
+	x4 = ap.x4;
+	fx = ap.fx;
+	fy = ap.fy;
+	return *this;
+}
+
+void H_Aperture::printProperties() const {
+        cout << "Aperture shape:" << getTypeString() << ", parameters "<<x1<<", "<<x2<<", "<<x3<<", "<<x4<<endl;
+        cout << " \t Center : " << fx << "," << fy << endl;
+        return;
+}
+
+void H_Aperture::setPosition(const float posx, const float posy) {
+	/// @param posx, posy are the (x,y) coordinates of the center of the apertures [m]
+	// posx, posy, fx, fy = [m]
+	fx = posx;
+	fy = posy;
+	return;
+}
+
+bool H_Aperture::isInside(const float x, const float y) const {
+        /// @param x, y are the (x,y) coordinates of the proton, in [m]
+        //cout << "aperture::isInside" << endl;
+        return false;
+}
+
+
+void H_Aperture::setApertureString() {
+	switch (type) {
+		case NONE: aptypestring = NONENAME; break;
+ 		case RECTANGULAR: aptypestring = RECTANGULARNAME; break;
+ 		case ELLIPTIC: aptypestring = ELLIPTICNAME; break;
+ 		case CIRCULAR: aptypestring = CIRCULARNAME; break;
+ 		case RECTELLIPSE: aptypestring = RECTELLIPSENAME; break;
+		default: aptypestring = NONENAME; break;
+	}
+}
Index: /trunk/Utilities/Hector/src/H_Beam.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_Beam.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_Beam.cc	(revision 3)
@@ -0,0 +1,526 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Beam.cc
+/// \brief Describes a set a particles as a beam
+///
+
+// ROOT #includes
+#include "TGraph.h"
+#include "TRandom.h"
+
+// local #includes
+#include "H_Beam.h"
+using namespace std;
+
+H_Beam::H_Beam() {
+        setPosition(PX,PY,TX+CRANG,TY,PS);
+        setE(BE);
+        setDispersion(SX,SY,STX,STY,SS);
+        setDE(SBE);
+	Nparticles=0;
+}
+
+H_Beam::H_Beam(const H_Beam& be) {
+	beamParticles = be.beamParticles;
+	setPosition(be.fx_ini,be.fy_ini,tx_ini,ty_ini,be.fs_ini);
+	setE(be.fe_ini);
+	setDispersion(be.x_disp,be.y_disp,be.tx_disp,be.ty_disp,be.s_disp);
+	setDE(be.e_disp);
+	Nparticles = be.Nparticles;
+}
+
+H_Beam& H_Beam::operator=(const H_Beam& be) {
+	if(this==&be) return *this;
+        beamParticles = be.beamParticles;
+        setPosition(be.fx_ini,be.fy_ini,tx_ini,ty_ini,be.fs_ini);
+        setE(be.fe_ini);
+        setDispersion(be.x_disp,be.y_disp,be.tx_disp,be.ty_disp,be.s_disp);
+        setDE(be.e_disp);
+        Nparticles = be.Nparticles; 
+        return *this;
+}
+
+H_Beam::~H_Beam() {
+	beamParticles.clear(); 
+	return;
+};
+
+void H_Beam::createBeamParticles(const unsigned int Number_of_particles) {
+	createBeamParticles(Number_of_particles,MP,QP);
+}
+
+void H_Beam::createBeamParticles(const unsigned int Number_of_particles, const double p_mass, const double p_charge) {
+	beamParticles.clear();
+	Nparticles = (Number_of_particles<1) ? 1 : Number_of_particles;
+	for (unsigned int i=0; i<Nparticles; i++) {
+		H_BeamParticle p(p_mass,p_charge);
+		p.setPosition(fx_ini,fy_ini,tx_ini,ty_ini,fs_ini);
+		p.setE(fe_ini);
+		p.smearPos(x_disp,y_disp);
+		p.smearAng(tx_disp,ty_disp);
+		p.smearE(e_disp);
+		p.smearS(s_disp);
+		if (VERBOSE) {if (i==0) cout << " x_ini , tx_ini " << p.getX() << " " << p.getTX() << endl;}
+		beamParticles.push_back(p);
+	}
+}
+
+//void H_Beam::particleGun(const unsigned int Number_of_particles, const float E_min=BE, const float E_max=BE, const float fs_min=0, const float fs_max=0, const float fx_min=0, const float fx_max=0, const float fy_min=0, const float fy_max=0, const float tx_min=-PI/2., const float tx_max=PI/2., const float ty_min=-PI/2., const float ty_max=PI/2., const float p_mass=MP, const double p_charge=QP) {
+void H_Beam::particleGun(const unsigned int Number_of_particles, const float E_min, const float E_max, const float fs_min, const float fs_max, const float fx_min, const float fx_max, const float fy_min, const float fy_max, const float tx_min, const float tx_max, const float ty_min, const float ty_max, const float p_mass, const double p_charge, const bool flat) {
+        beamParticles.clear();
+        Nparticles = (Number_of_particles<2) ? 2 : Number_of_particles;
+        float gx,gy,gs,gtx,gty,gE;
+        for (unsigned int i=0; i<Nparticles; i++) {
+                H_BeamParticle p(p_mass,p_charge);
+                if (flat) {
+                        gx = gRandom->Uniform(fx_min,fx_max);
+                        gy = gRandom->Uniform(fy_min,fy_max);
+                        gs = gRandom->Uniform(fs_min,fs_max);
+                        gtx = gRandom->Uniform(tx_min,tx_max);
+                        gty = gRandom->Uniform(ty_min,ty_max);
+                        gE = gRandom->Uniform(E_min,E_max);
+                } else {
+                        gx = gRandom->Gaus((fx_min+fx_max)/2,(-fx_min+fx_max)/2);
+                        gy = gRandom->Gaus((fy_min+fy_max)/2,(-fy_min+fy_max)/2);
+                        gs = gRandom->Gaus((fs_min+fs_max)/2,(-fs_min+fs_max)/2);
+                        gtx = gRandom->Gaus((tx_min+tx_max)/2,(-tx_min+tx_max)/2);
+                        gty = gRandom->Gaus((ty_min+ty_max)/2,(-ty_min+ty_max)/2);
+                        gE = gRandom->Gaus ((E_min+E_max)/2,(-E_min+E_max)/2);
+                }
+                p.setPosition(gx,gy,gtx,gty,gs);
+                p.setE(gE);
+                beamParticles.push_back(p);
+        }
+        return;
+}
+
+
+void H_Beam::createXScanningBeamParticles(const unsigned int Number_of_particles, const float fx_max) {
+        beamParticles.clear();
+	Nparticles = (Number_of_particles<2) ? 2 : Number_of_particles;
+        for (unsigned int i=0; i<Nparticles; i++) {
+                H_BeamParticle p;
+		float fx = fx_ini + i/(float)(Nparticles-1) * (fx_max-fx_ini);
+                p.setPosition(fx,fy_ini,0,0,fs_ini);
+                p.setE(fe_ini);
+                beamParticles.push_back(p);
+        }
+}
+
+void H_Beam::createYScanningBeamParticles(const unsigned int Number_of_particles, const float fy_max) {
+
+        beamParticles.clear();
+	Nparticles = (Number_of_particles<2) ? 2 : Number_of_particles;
+        for (unsigned int i=0; i<Nparticles; i++) {
+                H_BeamParticle p;
+                float fy = fy_ini + i/(float)(Nparticles-1) * (fy_max-fy_ini);
+                p.setPosition(fx_ini,fy,0,0,fs_ini);
+                p.setE(fe_ini);
+                beamParticles.push_back(p);
+        }
+}
+
+void H_Beam::createTXScanningBeamParticles(const unsigned int Number_of_particles, const float tx_max) {
+        beamParticles.clear();
+	Nparticles = (Number_of_particles<2) ? 2 : Number_of_particles;
+        for (unsigned int i=0; i<Nparticles; i++) {
+                H_BeamParticle p;
+                float tx = tx_ini + i/(float)(Nparticles-1) * (tx_max-tx_ini);
+                p.setPosition(fx_ini,fy_ini,tx,ty_ini,fs_ini);
+                p.setE(fe_ini);
+                beamParticles.push_back(p);
+        }
+}
+
+void H_Beam::createTYScanningBeamParticles(const unsigned int Number_of_particles, const float ty_max) {
+        beamParticles.clear(); 
+        Nparticles = (Number_of_particles<2) ? 2 : Number_of_particles;
+        for (unsigned int i=0; i<Nparticles; i++) { 
+                H_BeamParticle p; 
+                float ty = ty_ini + i/(float)(Nparticles-1) * (ty_max-ty_ini);
+                p.setPosition(fx_ini,fy_ini,tx_ini,ty,fs_ini);
+                p.setE(fe_ini); 
+                beamParticles.push_back(p); 
+        } 
+}
+
+const H_BeamParticle * H_Beam::getBeamParticle(const unsigned int particle_index) const {
+//	const int N = (particle_index<0)?0:(( particle_index>Nparticles)?Nparticles:particle_index);
+	const int N = (particle_index>Nparticles)?Nparticles:particle_index;
+	return &(*(beamParticles.begin()+N));// same as "return &beamParticles[N];" but more efficient
+}
+
+H_BeamParticle * H_Beam::getBeamParticle(const unsigned int particle_index) {
+//        const int N = (particle_index<0)?0:(( particle_index>Nparticles)?Nparticles:particle_index);
+	const int N = (particle_index>Nparticles)?Nparticles:particle_index;
+        return &(*(beamParticles.begin()+N));// same as "return &beamParticles[N];" but more efficient
+}
+
+void H_Beam::add(const H_BeamParticle &p) {
+	beamParticles.push_back(p);
+	Nparticles++;
+}
+
+void H_Beam::computePath(const H_AbstractBeamLine * beamline, const bool NonLinear) {
+	vector<H_BeamParticle>::iterator particle_i;
+
+	for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+		particle_i->computePath(beamline,NonLinear);	
+	}
+}
+
+void H_Beam::computePath(const H_AbstractBeamLine * beamline) {
+	computePath(beamline,false);
+}
+
+/// Propagates the beam until a given s
+void H_Beam::propagate(const float position) {
+	vector<H_BeamParticle>::iterator particle_i;
+	for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+                particle_i->propagate(position);
+        }
+}
+
+void H_Beam::emitGamma(const double gee, const double gq2) {
+	/// @param gee = \f$ E_{\gamma} \f$ is the photon energy
+	/// @param gq2 = \f$ Q^2 < 0 \f$ is virtuality of photon \f$ Q^{2} = E^{2}-\vec{k}^{2} \f$
+	emitGamma(gee,gq2,0,2*PI);
+}
+
+void H_Beam::emitGamma(const double gee, const double gq2, const double phimin, const double phimax) {
+	/// @param gee = \f$ E_{\gamma} \f$ is the photon energy
+	/// @param gq2 = \f$ Q^2 < 0 \f$ is virtuality of photon \f$ Q^{2} = E^{2}-\vec{k}^{2} \f$
+	/// @param phimin : lower bound for \f$ \phi \f$
+	/// @param phimax : higher bound for \f$ \phi \f$
+	vector<H_BeamParticle>::iterator particle_i;
+	for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++)
+                particle_i->emitGamma(gee,gq2,phimin,phimax);
+}
+
+float H_Beam::getBetaX(const float s, float& error_on_betax) {
+	/// @param s is the position [m] to propagate to
+	/// @param error_on_betax : getBetaX(...) returns its error in this variable
+	/// not a const method because does a propagate to s!
+	vector<H_BeamParticle>::iterator particle_i;
+	float EX2=0,dummy, mean=getX(s,dummy), temp;
+
+	for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+		particle_i->propagate(s);
+		temp = particle_i->getX()-mean;
+		EX2 += temp*temp;
+	}
+	EX2 /= (float)Nparticles;
+	float emitx = getEmittanceX();	
+	EX2 = (emitx==0)?0:(float) (EX2 /(float) (emitx*URAD))/URAD;
+	error_on_betax = EX2 / (float) sqrt((double)2*Nparticles);
+	return EX2;
+}
+
+float H_Beam::getBetaY(const float s, float& error_on_betay) {
+        /// @param s is the position [m] to propagate to
+        /// @param error_on_betay : getBetaY(...) returns its error in this variable
+	/// not a const method because does a propagate to s!
+ 	vector<H_BeamParticle>::iterator particle_i;
+	float EY2 =0, dummy, mean=getY(s,dummy), temp;
+
+        for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+                particle_i->propagate(s);
+		temp = particle_i->getY() - mean;
+		EY2 += temp*temp;
+	}
+	EY2 /= (float)Nparticles;
+	float emity = getEmittanceY();
+	EY2 = (emity==0)?0:(float) (EY2 / (float) (emity*URAD))/URAD;
+	error_on_betay = EY2 / (float) sqrt((double)2*Nparticles);
+	return EY2;
+}
+
+TGraphErrors * H_Beam::getBetaX(const float length, const unsigned int number_of_points) {
+	/// @param length [m]
+	/// @number_of_points in the graph (typ. 200)
+	const unsigned int N = number_of_points;
+	float * s = new float[N], * b = new float[N], * es = new float[N], * eb = new float[N];
+	for (unsigned int i=0; i<N; i++) {
+		s[i] = (float) fs_ini + i/(float)(N-1) *length; 
+		b[i] = getBetaX(s[i],eb[i]);
+		es[i] = 0;
+	}
+	TGraphErrors * betax = new TGraphErrors(N,s,b,es,eb);
+	betax->SetLineColor(kBlack);
+	betax->SetFillColor(kYellow);
+	delete [] s;
+	delete [] b;
+	delete [] es;
+	delete [] eb;
+	return betax;
+}
+
+TGraphErrors * H_Beam::getBetaY(const float length, const unsigned int number_of_points) {
+        /// @param length [m] 
+        /// @number_of_points in the graph (typ. 200)
+        const unsigned int N = number_of_points;
+        float * s = new float[N], * b = new float[N], * es = new float[N], *eb = new float[N];
+        for (unsigned int i=0; i<N; i++) {
+                s[i] = (float) fs_ini + i/(float)(N-1) *length;
+                b[i] = getBetaY(s[i],eb[i]);
+		es[i]=0;
+        }
+        TGraphErrors * betay = new TGraphErrors(N,s,b,es,eb);
+        betay->SetLineColor(kRed);
+	betay->SetFillColor(kYellow);
+        delete [] s;
+        delete [] b;
+        delete [] es;
+        delete [] eb;
+	return betay;
+}
+
+float H_Beam::getX(const float s, float& error_on_posx) {
+	vector<H_BeamParticle>::iterator particle_i;
+	float mean=0;
+
+        for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+                particle_i->propagate(s);
+                mean += particle_i->getX();
+        }
+	mean = mean / (float) Nparticles;
+	error_on_posx = mean / (float) sqrt((double)Nparticles);
+        return mean;
+}
+
+float H_Beam::getY(const float s, float& error_on_posy) {
+	vector<H_BeamParticle>::iterator particle_i;
+	float mean=0;
+
+        for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+                particle_i->propagate(s);
+        	mean += particle_i->getY();
+	}
+	mean = mean / (float) Nparticles;
+	error_on_posy = mean / (float) sqrt((double)Nparticles);
+        return mean;
+}
+
+unsigned int H_Beam::getStoppedNumber(const H_AbstractBeamLine * beamline) {
+	int number =0;
+	vector<H_BeamParticle>::iterator particle_i;
+	for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+		if(particle_i->stopped(beamline)) number++;
+	}
+	return number;
+}
+
+vector<TVectorD> H_Beam::getStoppingElements(const H_AbstractBeamLine * beamline, vector<H_OpticalElement>& list, vector<int>& numb) {
+
+		vector<TVectorD> stop_positions;
+        vector<H_BeamParticle>::iterator particle_i;
+        vector<H_OpticalElement>::iterator element_i;
+        H_OpticalElement temp_el;
+        vector<int>::iterator n_i;
+        int number =0;
+        bool found;
+
+        list.clear();
+        numb.clear();
+
+        // creates a list of elements where beamParticles have stopped
+        for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+                found = false;
+                if(particle_i->stopped(beamline)) {
+                        temp_el = *(particle_i->getStoppingElement());
+						stop_positions.push_back(*(particle_i->getStopPosition()));
+                        if(list.size()==0) {
+                                number=1;
+                                list.push_back(temp_el);
+                                numb.push_back(number);
+
+                        } else {
+                                for (element_i = list.begin(), n_i = numb.begin(); element_i < list.end(); element_i++, n_i++) {
+                                        string el_i_name = element_i->getName();
+                                        string temp_el_name = temp_el.getName();
+                                        if(el_i_name == temp_el_name) {
+                                                number = *n_i;
+                                                number++;
+                                                *n_i = number;
+                                                found = true;
+                                        }
+                                }
+                                if(!found) {
+                                                number=1;
+                                                list.push_back(temp_el);
+                                                numb.push_back(number);
+                                }
+                        }
+                } // if particle_i->stopped
+        }// for particle_i
+		return stop_positions;
+} // H_Beam::getStoppingElements
+
+void H_Beam::printInitialState() const {
+	cout << "Initial parameters of the beam" << endl;
+	cout << "(x,y,s) = (" << fx_ini << "," << fy_ini << "," << fs_ini << ") ";
+	cout << "(theta_x, theta_y) = (" << tx_ini << "," << ty_ini << ") ";
+	cout << "energy = " << fe_ini << endl; 
+	cout << endl;
+	cout << "Dispersion on these values : " << endl;
+	cout << "(dx,dy,ds) = (" << x_disp << "," << y_disp << "," << s_disp << ") ";
+	cout << "(dtheta_x, dtheta_y) = (" << tx_disp << "," << ty_disp << ") ";
+	cout << "de = " << e_disp << endl << endl;
+
+	float mean_ini =0;
+	vector<H_BeamParticle>::const_iterator particle_i;
+	for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+		mean_ini += particle_i->getX();
+	}
+	mean_ini /= (float) beamParticles.size();
+	cout << "Mean ini x = " << mean_ini << endl;
+}
+
+void H_Beam::printProperties() const {
+	vector<H_BeamParticle>::const_iterator particle_i;
+	cout << "There are " << Nparticles << " in the beam." << endl;
+	for (particle_i = beamParticles.begin();particle_i < beamParticles.end(); particle_i++) {
+		particle_i->printProperties();
+	}
+}
+
+void H_Beam::printStoppingElements(const vector<H_OpticalElement>& list, const vector<int>& numb) const{
+	/// see also H_Beam::getStoppingElements
+	vector<H_OpticalElement>::const_iterator element_i;
+	vector<int>::const_iterator n_i;
+
+	// prints the list
+	for (element_i=list.begin(), n_i = numb.begin(); element_i < list.end(); element_i++, n_i++) {
+		cout << *n_i << " particules in " << element_i->getName();
+		cout <<  " (" << element_i->getTypeString() << ") at " << element_i->getS() << "m" << endl;
+		element_i->getAperture()->printProperties();
+	}
+} // H_Beam::printStoppingElements
+
+TH2F *  H_Beam::drawAngleProfile(const float s) {
+        /// not a const method because does a propagate to s!
+        char title[50];
+        sprintf(title,"Beam profile at %.2f m",s);
+        vector<H_BeamParticle>::iterator particle_i;
+        float xmax, xmin, ymax, ymin;
+        float xx, yy, xborder, yborder;
+
+        particle_i=beamParticles.begin();
+        xmin = particle_i->getTX();
+        xmax = particle_i->getTX();
+        ymin = particle_i->getTY();
+        ymax = particle_i->getTY();
+
+        for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+                particle_i->propagate(s);
+                xx = particle_i->getTX();
+                yy = particle_i->getTY();
+
+                xmax = xx>xmax ? xx : xmax;
+                ymax = yy>ymax ? yy : ymax;
+                xmin = xx<xmin ? xx : xmin;
+                ymin = yy<ymin ? yy : ymin;
+        }
+
+        // in order to avoid some drawing problems, when the beam divergence is null
+        if(!(xmax || xmin)) xmax +=0.1;
+        if(!(ymax || ymin)) xmax +=0.1;
+
+        if(xmax == xmin) xmax *= 1.1;
+        if(ymax == ymin) ymax *= 1.1;
+
+        xborder = (xmax-xmin)*0.2;
+        yborder = (ymax-ymin)*0.2;
+
+        xmax += xborder;
+        xmin -= xborder;
+        ymax += yborder;
+        ymin -= yborder;
+
+        TH2F * profile = new TH2F("profile",title,10000,xmin,xmax,1000,ymin,ymax);
+        for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+                profile->Fill(particle_i->getTX(), particle_i->getTY());
+        }
+        return profile;
+}
+
+
+TH2F *  H_Beam::drawProfile(const float s) {
+	/// not a const method because does a propagate to s!
+	char title[50];
+	sprintf(title,"Beam profile at %.2f m",s);
+	vector<H_BeamParticle>::iterator particle_i;
+	float xmax, xmin, ymax, ymin;
+	float xx, yy, xborder, yborder;
+
+	particle_i=beamParticles.begin();
+	xmin = particle_i->getX();
+	xmax = particle_i->getX();
+	ymin = particle_i->getY();
+        ymax = particle_i->getY();
+
+	for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+                particle_i->propagate(s);
+		xx = particle_i->getX();
+		yy = particle_i->getY();
+
+                xmax = xx>xmax ? xx : xmax;
+		ymax = yy>ymax ? yy : ymax;
+		xmin = xx<xmin ? xx : xmin;
+		ymin = yy<ymin ? yy : ymin;
+        }
+
+	// in order to avoid some drawing problems, when the beam divergence is null
+        if(!(xmax || xmin)) xmax +=0.1;
+        if(!(ymax || ymin)) xmax +=0.1;
+
+	if(xmax == xmin) xmax += 0.1;
+	if(ymax == ymin) ymax += 0.1;
+	
+	xborder = (xmax-xmin)*0.2;
+	yborder = (ymax-ymin)*0.2;
+
+	xmax += xborder;
+	xmin -= xborder;
+	ymax += yborder;
+	ymin -= yborder;
+
+	TH2F * profile = new TH2F("profile",title,10000,xmin,xmax,1000,ymin,ymax);
+        for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+		profile->Fill(particle_i->getX(), particle_i->getY());
+	}
+	return profile;
+}
+
+TMultiGraph * H_Beam::drawBeamX(const int color) const {
+	int mycolor = color;
+	vector<H_BeamParticle>::const_iterator particle_i;
+	TMultiGraph * beam_profile_x = new TMultiGraph("beam_profile_x","");
+	
+	for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+		TGraph * ppath_x = particle_i->getPath(0,mycolor);
+		beam_profile_x->Add(ppath_x);
+	}
+	return beam_profile_x;
+}
+
+TMultiGraph * H_Beam::drawBeamY(const int color) const {
+	int mycolor = color;
+        vector<H_BeamParticle>::const_iterator particle_i;
+        TMultiGraph * beam_profile_y = new TMultiGraph("beam_profile_y","");
+
+        for (particle_i = beamParticles.begin(); particle_i < beamParticles.end(); particle_i++) {
+                TGraph * ppath_y = particle_i->getPath(1,mycolor);
+                beam_profile_y->Add(ppath_y);
+        }
+        return beam_profile_y;
+}
Index: /trunk/Utilities/Hector/src/H_BeamLine.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_BeamLine.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_BeamLine.cc	(revision 3)
@@ -0,0 +1,254 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_BeamLine.cc
+/// \brief Reads external files and retrieves features of the real beam optical elements
+
+// c++ #includes
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+// local #includes
+#include "H_BeamLine.h"
+#include "H_BeamLineParser.h"
+#include "H_RectEllipticAperture.h"
+#include "H_RectangularAperture.h"
+#include "H_EllipticAperture.h"
+#include "H_CircularAperture.h"
+#include "H_RectangularDipole.h"
+#include "H_SectorDipole.h"
+#include "H_HorizontalQuadrupole.h"
+#include "H_VerticalQuadrupole.h"
+#include "H_HorizontalKicker.h"
+#include "H_VerticalKicker.h"
+#include "H_RectangularCollimator.h"
+#include "H_Marker.h"
+
+using namespace std;
+
+// Caution : mad conventions for vertically(horizontally) focusing quadrupoles
+// are opposite to Wille's. See fill() for more details.
+
+H_BeamLine::H_BeamLine(const int si, const float length) : H_AbstractBeamLine(length){
+	direction = (si >= abs(si)) ? 1 : -1;
+	ips=0;
+	ipx=0;
+	ipy=0;
+	iptx=0;
+	ipty=0;
+}
+
+H_BeamLine::H_BeamLine(const H_BeamLine& beam) : H_AbstractBeamLine(beam) {
+	direction = beam.direction;
+	ips = beam.ips;
+	ipx = beam.ipx;
+	ipy = beam.ipy;
+	iptx = beam.iptx;
+	ipty = beam.ipty;
+}
+
+H_BeamLine& H_BeamLine::operator=(const H_BeamLine& beam) {
+	if(this==&beam) return *this;
+	direction = beam.direction;
+	ips = beam.ips;
+	ipx = beam.ipx;
+    ipy = beam.ipy;
+    iptx = beam.iptx;
+    ipty = beam.ipty;
+	return *this;
+}
+
+void H_BeamLine::findIP(const string filename) {
+	findIP(filename,"IP5");
+	return;
+}
+
+void H_BeamLine::findIP(const string filename, const string ipname) {
+	// searches for the IP position in the extended table.
+	ifstream tabfile(filename.c_str());
+		if (! tabfile.is_open()) cout << "<H_BeamLine> ERROR: I Can't open \"" << filename << "\"" << endl;
+	bool found = false;
+	int N_col=0;
+	string headers[40];  // table of all column headers
+	int header_type[40]; // table of all column types
+
+	string temp_string;
+	H_BeamLineParser e;
+	istringstream curstring;
+
+	while (	getline(tabfile,temp_string)) {
+		curstring.clear(); // needed when using istringstream::str(string) several times !
+		curstring.str(temp_string);
+
+		// gets the features of each element
+		if (found) {
+			for (int col=0; col < N_col; col++) e.setProperties(curstring,header_type[col]);
+			if(strstr(e.name.c_str(),ipname.c_str())) {
+				ips = e.s; //e.printProperties();
+				ipx = e.x;
+				ipy = e.y;
+				iptx = e.px*URAD;
+				ipty = e.py*URAD;
+			}
+		} else if (strstr(temp_string.c_str(),"K0L")) {  //searches for the beginning of the element list.
+			found = true;
+
+			// reads the title of each column
+			while(curstring.good()) { curstring >> headers[N_col]; if(headers[N_col]!="*") N_col++;}
+			if(VERBOSE) cout << N_col << " columns identified" << endl;
+
+			// identifies each column
+			for (int col=0; col< N_col; col++)	header_type[col] =  column_identification(headers[col]);
+			
+			getline(tabfile,temp_string); // skip one line
+		} // if(... "K0L")
+	} // while (!eof)
+
+	if (!found) cout << "<H_BeamLine> ERROR ! IP not found." << endl;
+	tabfile.close();
+}
+
+double* H_BeamLine::getIPProperties() {
+	double* temp = new double[4];
+	temp[0] = ipx;
+	temp[1] = ipy;
+	temp[2] = iptx;
+	temp[3] = ipty;
+	return temp;
+}
+
+void H_BeamLine::fill(const string filename) {
+	fill(filename,1,"IP5");
+	return;
+}
+
+
+void H_BeamLine::fill(const string filename, const int dir, const string ipname) {
+	string headers[40];  // table of all column headers
+	int header_type[40]; // table of all column types
+	findIP(filename,ipname);
+	ifstream tabfile(filename.c_str());
+		if (! tabfile.is_open()) cout << "<H_BeamLine> ERROR: I Can't open \"" << filename << "\"" << endl;
+	if(VERBOSE) {
+		cout<<"Using file : "<< filename <<" in the "<<((direction>0)?"positive":"negative")<<" direction."<<endl;
+		cout<<"IP was found at position : "<<ips<<endl<<endl;
+	}
+	bool found = false; // found = true when the beginning of the element list is reached
+	int type, N_col=0;
+	float previous_betax =0, previous_betay=0; // needed when direction ==1
+	float previous_dx =0, previous_dy=0; // needed when direction ==1
+	float previous_x =0, previous_y=0; // needed when direction ==1
+
+	string temp_string;
+	H_BeamLineParser e;
+	istringstream curstring;
+	H_OpticalElement *el = 0;
+	H_Aperture * ap = 0;
+
+
+	while (getline(tabfile,temp_string)) {
+		curstring.clear(); // needed when using several tims istringstream::str(string)
+		curstring.str(temp_string);
+
+        // gets the features of each element
+		if (found) {
+			// reads each column
+			for (int col=0; col < N_col; col++) {
+				e.setProperties(curstring,header_type[col]);
+			}
+			//e.printProperties();
+			
+			type =0; //init
+			if(e.k0l!=0) { if(strstr(e.name.c_str(),"MB.")) type = SDIPOLE; else type = RDIPOLE;} //all SBEND seems to be called MB.xxxxx.xx
+			else if(e.k1l!=0) type = (e.k1l>0)?HQUADRUPOLE:VQUADRUPOLE;
+			else if(e.hkick!=0) type = HKICKER;
+			else if(e.vkick!=0) type = VKICKER;
+			else if(strstr(e.name.c_str(),"DRIFT")) type=DRIFT;
+			else if((strstr(e.name.c_str(),"DFB"))||(strstr(e.name.c_str(),"TAS"))||(strstr(e.name.c_str(),"TAN"))||(strstr(e.name.c_str(),"TCL"))) type = RCOLLIMATOR;
+			else if(strstr(e.name.c_str(),ipname.c_str())) { type=IP; }
+			else type=MARKER;
+			
+			e.s = (e.s > ips) ? (e.s -ips - e.l)*(direction) : (e.s-ips)*(direction);
+			
+			el=0; //init
+			switch(type) {
+				case RDIPOLE:     { el = new H_RectangularDipole(e.name.c_str(),e.s,dir*e.k0l/e.l,e.l); } break;
+				case SDIPOLE:     { el = new H_SectorDipole(e.name.c_str(),e.s,dir*e.k0l/e.l,e.l); } break;
+				case VQUADRUPOLE: { el = new H_VerticalQuadrupole(e.name.c_str(),e.s,-(e.k1l/e.l),e.l); } break;
+				case HQUADRUPOLE: { el = new H_HorizontalQuadrupole(e.name.c_str(),e.s,-(e.k1l/e.l),e.l); } break;
+				case VKICKER:     { el = new H_VerticalKicker(e.name.c_str(),e.s,e.vkick,e.l); } break;
+				case HKICKER:     { el = new H_HorizontalKicker(e.name.c_str(),e.s,e.hkick,e.l); } break;
+				case RCOLLIMATOR: { el = new H_RectangularCollimator(e.name.c_str(),e.s,e.l); } break;
+				case DRIFT: {previous_betax = e.betx; previous_betay = e.bety; previous_dx = e.dx; previous_dy = e.dy; previous_x = e.x; previous_y = e.y;} break;
+				case IP: { el = new H_Marker(e.name.c_str(),e.s); } break;
+				default: break;
+			}
+
+			ap = 0; //init
+			if(e.aper_1 !=0 || e.aper_2 !=0 || e.aper_3 !=0 || e.aper_4 != 0) {
+				e.aper_1 *= URAD;
+				e.aper_2 *= URAD;
+				e.aper_3 *= URAD;
+				e.aper_4 *= URAD; // in [m] in the tables !
+
+				if(strstr(e.apertype.c_str(),"RECTELLIPSE")) ap = new H_RectEllipticAperture(e.aper_1,e.aper_2,e.aper_3,e.aper_4,0,0);
+				else if(strstr(e.apertype.c_str(),"CIRCLE")) ap = new H_CircularAperture(e.aper_1,0,0);
+				else if(strstr(e.apertype.c_str(),"RECTANGLE")) ap = new H_RectangularAperture(e.aper_1,e.aper_2,0,0);
+				else if(strstr(e.apertype.c_str(),"ELLIPSE")) ap = new H_EllipticAperture(e.aper_1,e.aper_2,0,0);
+			}
+
+			if(el!=0) {
+				if (direction<0) {
+					el->setBetaX(e.betx);
+					el->setBetaY(e.bety);
+					el->setDX(e.dx);
+					el->setDY(e.dy);
+					el->setRelX(e.x);
+					el->setRelY(e.y);
+				} else {
+					el->setBetaX(previous_betax);
+					el->setBetaY(previous_betay);
+					el->setDX(previous_dx);
+					el->setDY(previous_dy);
+					el->setRelX(previous_x);
+					el->setRelY(previous_y);
+				}
+				if(ap!=0) { 
+					el->setAperture(ap);  // makes a copy
+					delete ap; 
+				}
+	
+				/// Parses all the elements, but only keeps the ones from the IP till the desired length
+				if(e.s>=0 && e.s<beam_length) add(*el);
+
+			// delete el; // el deleted in H_AbstractBeamLine::~H_AbstractBeamLine
+			} // if(el!=0)
+		} // if (found)
+		else if(strstr(temp_string.c_str(),"K0L")) { // if (!found)
+		//searches for the beginning of the element list.
+			found = true;
+
+			// reads the title of each column
+			while(curstring.good()) { curstring >> headers[N_col]; if(headers[N_col]!="*") N_col++;}
+			if(VERBOSE) cout << N_col << " columns identified" << endl;
+
+			// identifies each column
+			for (int col=0; col< N_col; col++) {
+				header_type[col] =  column_identification(headers[col]);
+			}
+			getline(tabfile,temp_string);
+		} // if temp_string <-> "K0L"
+
+	} // while (!eof)
+	tabfile.close();
+}
+
Index: /trunk/Utilities/Hector/src/H_BeamLineParser.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_BeamLineParser.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_BeamLineParser.cc	(revision 3)
@@ -0,0 +1,129 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_BeamLineParser.cc
+/// \brief Reader for madx tables
+///
+/// Notes : Vï¿œifier que tous les SBEND sont toujours appelï¿œ MB. Et seulement comme ï¿œ !
+/// Vï¿œifier qu'il n'y a pas de problï¿œe d'inversion H/V QUADRUPOLES
+/// no distinction between H and Vkickers ?
+/// The identification of the element is based on the values of k1l, k2l, hkick, vkick and on their name.
+/// x and y are put in m
+
+// c++ #includes
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+//local #includes
+#include "H_BeamLineParser.h"
+#include "H_Parameters.h"
+using namespace std;
+
+
+/// Identifies the column content from its header
+int column_identification(const string header) {
+	// identifies the column type from its name
+
+	     if (header=="NAME")    {return MADX_NAME; }
+	else if (header=="KEYWORD") {return MADX_KEYWORD; }
+	else if (header=="S")       {return MADX_S; }
+	else if (header=="L")       {return MADX_L; }
+	else if (header=="K0L")     {return MADX_K0L; }
+	else if (header=="K1L")     {return MADX_K1L;}
+	else if (header=="K2L")     {return MADX_K2L;}
+	else if (header=="K3L")     {return MADX_K3L;}
+	else if (header=="HKICK")   {return MADX_HKICK;}
+	else if (header=="VKICK")   {return MADX_VKICK;}
+	else if (header=="KICK")    {return MADX_KICK;}
+	else if (header=="BETX")    {return MADX_BETX;}
+	else if (header=="BETY")    {return MADX_BETY;}
+	else if (header=="ALFX")    {return MADX_ALFX;}
+	else if (header=="ALFY")    {return MADX_ALFY;}
+	else if (header=="MUX")     {return MADX_MUX;}
+	else if (header=="MUY")     {return MADX_MUY;}
+	else if (header=="DX")      {return MADX_DX;}
+	else if (header=="DY")      {return MADX_DY;}
+	else if (header=="DPX")     {return MADX_DPX;}
+	else if (header=="DPY")     {return MADX_DPY;}
+	else if (header=="X")       {return MADX_X;}
+	else if (header=="Y")       {return MADX_Y;}
+	else if (header=="PX")      {return MADX_PX;}
+	else if (header=="PY")      {return MADX_PY;}
+	else if (header=="APERTYPE") {return MADX_APERTYPE;}
+	else if (header=="APER_1")  {return MADX_APER_1;}
+	else if (header=="APER_2")  {return MADX_APER_2;}
+	else if (header=="APER_3")  {return MADX_APER_3;}
+	else if (header=="APER_4")  {return MADX_APER_4;}
+	else if (header=="PARENT")  {return MADX_PARENT;}
+	return MADX_UNKNOWN;
+}
+
+void H_BeamLineParser::init() {
+	name=""; 
+	apertype="";
+	keyword="";
+	parent="";
+	s=0;  l=0;  k0l=0;  k1l=0;  k2l=0;  k3l=0;  hkick=0;  vkick=0;  betx=0;
+	alfx=0;  mux=0;  dx=0;  dpx=0;  x=0;  px=0;  bety=0;  alfy=0;  muy=0;
+	dy=0;  dpy=0;  y=0;  py=0;  aper_1=0;  aper_2=0;  aper_3=0;  aper_4=0;
+}
+
+void H_BeamLineParser::setProperties(istream& input, const unsigned int col_type) {
+
+	switch(col_type) {
+		case   MADX_NAME:    input >> name; break;
+		case   MADX_KEYWORD: input >> keyword; break;
+		case   MADX_S:       input >> s; break;
+		case   MADX_L:       input >> l;   break;
+		case   MADX_K0L:     input >> k0l; break;
+		case   MADX_K1L :    input >> k1l; break;
+		case   MADX_K2L:     input >> k2l; break;
+		case   MADX_K3L:     input >> k3l; break;
+		case   MADX_HKICK:   input >> hkick; break;
+		case   MADX_VKICK:   input >> vkick; break;
+		case   MADX_BETX:    input >> betx; break;
+		case   MADX_ALFX:    input >> alfx; break;
+		case   MADX_MUX:     input >> mux; break;
+		case   MADX_DX:      input >> dx; break;
+		case   MADX_DPX:     input >> dpx; break;
+		case   MADX_X:       input >> x; x *=URAD; break;
+		case   MADX_PX:      input >> px; break;
+		case   MADX_BETY:    input >> bety; break;
+		case   MADX_ALFY:    input >> alfy; break;
+		case   MADX_MUY:     input >> muy; break;
+		case   MADX_DY:      input >> dy; break;
+		case   MADX_DPY:     input >> dpy; break;
+		case   MADX_Y:       input >> y; y*=URAD; break;
+		case   MADX_PY:      input >> py; break;
+		case   MADX_APERTYPE: input >> apertype; break;
+		case   MADX_APER_1:  input >> aper_1; break;
+		case   MADX_APER_2:  input >> aper_2; break;
+		case   MADX_APER_3:  input >> aper_3; break;
+		case   MADX_APER_4:  input >> aper_4; break;
+ 		case   MADX_PARENT:  input >> parent; break;
+		default:break;
+	} // switch
+}
+
+
+void H_BeamLineParser::printProperties() const {
+//KEYWORD	NAME	PARENT	L	K0L	K1L	K2L	K3L	S	BETX	BETY	DX	DY	XC	YC	ALFX	ALFY	MUX	MUY	DPX	PXC	PYC
+	cout << " keyword = " << keyword;
+	cout << " name = " << name;
+	cout << " l = " << l;
+	cout << " k0l = " << k0l;
+	cout << " k1l = " << k1l;
+	cout << " k2l = " << k2l;
+	cout << " k3l = " << k3l;
+	cout << " s = " << s << endl;
+	cout << endl;
+}
Index: /trunk/Utilities/Hector/src/H_BeamParticle.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_BeamParticle.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_BeamParticle.cc	(revision 3)
@@ -0,0 +1,661 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_BeamParticle.cc
+/// \brief Class aiming at simulating a particle in the LHC beam
+
+// from IP to RP, with emission of a photon of defined energy and Q.
+// Units : angles [rad], distances [m], energies [GeV], c=[1].
+// !!! no comment statement at the end of a #define line !!!
+
+// c++ #includes
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <string>
+#include <cmath>
+
+// ROOT #includes
+#include "H_Parameters.h"
+#include "TRandom.h"
+#include "TVectorD.h"
+#ifdef _include_pythia_
+#include "TPythia6.h"
+#endif
+
+// local #includes
+#include "H_OpticalElement.h"
+#include "H_BeamParticle.h"
+#include "H_Drift.h"
+
+using namespace std;
+
+void H_BeamParticle::init() {
+	mp = MP;
+	qp = QP;
+        fx = 0;
+        fy = 0;
+        thx = 0;
+        thy = 0;
+        fs = 0;
+        energy = BE;
+        hasstopped = false;
+        hasemitted = false;
+	isphysical = true;
+	addPosition(fx,thx,fy,thy,fs);
+	stop_position = new TVectorD(LENGTH_VEC);
+	for (int i=0; i<LENGTH_VEC; i++) (*stop_position)[i] = -1;
+	stop_element = 0;
+}
+
+H_BeamParticle::H_BeamParticle() {
+	init();
+}
+
+H_BeamParticle::H_BeamParticle(const H_BeamParticle& p) {
+	mp = p.mp;
+	qp = p.qp;
+	fx = p.fx;
+	fy = p.fy;
+	thx = p.thx;
+	thy = p.thy;
+	fs = p.fs;
+	energy = p.energy;
+	hasstopped = p.hasstopped;
+	hasemitted = p.hasemitted;
+	isphysical = p.isphysical;
+	stop_position = new TVectorD(*(p.stop_position));
+	if(p.hasstopped) stop_element = new H_OpticalElement(*(p.stop_element)); 
+	positions = p.positions;
+}
+
+H_BeamParticle::H_BeamParticle(const double mass, const double charge) {
+	init();
+	mp = mass;
+	qp = (mass==0) ? 0 : charge;
+	/// rejects particles with mass = 0 and charge != 0
+}
+
+H_BeamParticle& H_BeamParticle::operator=(const H_BeamParticle& p) {
+	if(this==&p) return *this;
+	mp = p.mp;
+	qp = p.qp;
+        fx = p.fx;
+        fy = p.fy;
+        thx = p.thx;
+        thy = p.thy;
+        fs = p.fs;
+        energy = p.energy;
+        hasstopped = p.hasstopped;
+        hasemitted = p.hasemitted;
+	isphysical = p.isphysical;
+        stop_position = new TVectorD(*(p.stop_position));
+	if(p.hasstopped) stop_element = new H_OpticalElement(*(p.stop_element));
+        positions = p.positions;
+	return *this;
+}
+
+bool H_BeamParticle::stopped(const H_AbstractBeamLine * beamline) {
+	vector<TVectorD>::const_iterator position_i;
+	for(position_i = positions.begin(); position_i < positions.end()-1; position_i++) {
+		const unsigned int pos = position_i-positions.begin();
+		if(beamline->getElement(pos)->getAperture()->getType()!=NONE) {
+			bool has_passed_entrance = beamline->getElement(pos)->isInside((*position_i)[INDEX_X],(*position_i)[INDEX_Y]);
+			bool has_passed_exit     = beamline->getElement(pos)->isInside((*(position_i+1))[INDEX_X],(*(position_i+1))[INDEX_Y]);
+			// here we should distinguish between particles passing the input or not.
+			//  - particles not passing the input are logically stopped at the input position. period.
+			//  - particles passing the input but not the output are stopped somewhere in the element
+			//  - particles passing both the input and the output could have been stopped somewhere inside too (less likely)
+			if(!has_passed_entrance) {
+				if(VERBOSE) cout<<"Stopped at the entrance of "<<beamline->getElement(pos)->getName();
+				hasstopped=true;
+				stop_element = const_cast<H_OpticalElement*>(beamline->getElement(pos));
+				*stop_position = *position_i;
+				if(VERBOSE) cout<<" at s = "<<(*stop_position)[4]<<endl;
+				return hasstopped;
+			} else if (!has_passed_exit) {
+				if(VERBOSE) cout<<"Stopped inside "<<beamline->getElement(pos)->getName();
+				hasstopped=true;
+				stop_element = const_cast<H_OpticalElement*>(beamline->getElement(pos));
+				// this should be computed using the element-based method "H_OpticalElement::getHitPosition" (caution : always nonlinear).
+				*stop_position = beamline->getElement(pos)->getHitPosition(*position_i,BE-energy,mp,qp);
+				if(VERBOSE) cout<<" at s = "<<(*stop_position)[4]<<endl;
+				return hasstopped;
+			}
+/*
+			if(!(has_passed_entrance && has_passed_exit)) {
+				if(VERBOSE) cout<<"particle stopped at "<<(beamline->getElement(pos))->getName();
+				if(VERBOSE) cout<<" (s = "<<(*position_i)[4] << ")" << endl;
+				hasstopped=true;
+				stop_element = const_cast<H_OpticalElement*>(beamline->getElement(pos));
+				*stop_position = *position_i;
+				return hasstopped;
+			} // if
+*/
+		} // if
+	} // for
+	return hasstopped;
+}
+
+void H_BeamParticle::addPosition(const double x, const double tx, const double y, const double ty, const double s) {
+			// [x] = [y] = m ; [tx] = [ty] = rad; [s] = m
+		double xys[LENGTH_VEC];
+		xys[INDEX_X]=x;
+		xys[INDEX_TX]=tx;
+		xys[INDEX_Y]=y;
+		xys[INDEX_TY]=ty;
+		xys[INDEX_S]=s;
+		
+		TVectorD temp_vec(LENGTH_VEC,xys);
+		positions.push_back(temp_vec);
+}
+
+void H_BeamParticle::smearPos(const double dx,const double dy) {
+  // the beam is centered on (fx,fy) at IP
+        fx = gRandom->Gaus(fx,dx);
+        fy = gRandom->Gaus(fy,dy);
+	positions.clear();
+	addPosition(fx,thx,fy,thy,fs);
+	return;
+}
+
+void H_BeamParticle::smearPos() {
+  // the beam is centered on (fx,fy) at IP
+	fx = gRandom->Gaus(fx,SX);
+	fy = gRandom->Gaus(fy,SY);
+	positions.clear();
+	addPosition(fx,thx,fy,thy,fs);
+	return;
+}
+
+void H_BeamParticle::smearAng(const double tx, const double ty) {
+  // the beam transverse direction is centered on (thx,thy) at IP
+        thx = gRandom->Gaus(thx,tx);
+        thy = gRandom->Gaus(thy,ty);
+	positions.clear();
+	addPosition(fx,thx,fy,thy,fs);
+	return;
+}
+
+void H_BeamParticle::smearAng() {
+   // the beam transverse direction is centered on (thx,thy) at IP
+	thx = gRandom->Gaus(thx,STX);
+	thy = gRandom->Gaus(thy,STY);
+	positions.clear();
+	addPosition(fx,thx,fy,thy,fs);
+	return;
+}
+
+void H_BeamParticle::smearE(const double erre) {
+	energy = gRandom->Gaus(energy,erre);
+	return;
+}
+
+void H_BeamParticle::smearE() {
+	energy = gRandom->Gaus(energy,SBE);
+	return;
+}
+
+void H_BeamParticle::smearS(const double errs) {
+        fs= gRandom->Gaus(fs,errs);
+	positions.clear();
+	addPosition(fx,thx,fy,thy,fs);
+        return;
+}
+
+void H_BeamParticle::smearS() {
+        fs = gRandom->Gaus(fs,SS);
+	positions.clear();
+	addPosition(fx,thx,fy,thy,fs);
+        return;
+}
+
+void H_BeamParticle::set4Momentum(const double px, const double py, const double pz, const double ene) {
+	/// @param px, py, pz, ene is \f$ (\vec p , E) [GeV]\f$ 
+	///
+	/// Clears the H_BeamParticle::positions vector.
+	positions.clear();
+	if(pz==0) {
+		cout<<" ERROR in H_BeamParticle::set4Momentum : no momentum in the beamline direction !"<<endl;
+		return;
+	}
+        thx = thx + URAD*atan(px/pz);
+        thy = thy + URAD*atan(py/pz);
+        energy = ene;
+	positions.clear();
+        addPosition(fx,thx,fy,thy,fs);
+	return;
+}
+
+void H_BeamParticle::set4Momentum(const TLorentzVector& pmu) {
+	/// @param pmu is the particle 4-momentum \f$ p^\mu \f$
+	///
+	/// Clears the H_BeamParticle::positions vector.
+	set4Momentum(pmu.Px(), pmu.Py(), pmu.Pz(), pmu.E());
+}
+
+void H_BeamParticle::setE(const double ene) {
+	energy = ene;
+	return;
+}
+
+void H_BeamParticle::setPosition(const double x, const double y, const double tx, const double ty, const double s) {
+	/// @param x, y are the transverse positions in \f$ \mu \f$ m
+	/// @param tx, ty are the angles in \f$ \mu \f$ rad
+	/// @param s is the longitudinal coordinate in m
+	// clear positions and sets the initial one.
+		fx=x;
+		fy=y;
+		thx=tx;
+		thy=ty;
+		fs = s;
+		positions.clear();
+		addPosition(fx,thx,fy,thy,s);
+
+	return;
+}
+
+const H_OpticalElement* H_BeamParticle::getStoppingElement() const{
+	if(hasstopped) return stop_element;
+	else { H_OpticalElement * dummy_el = new H_Drift("",0,0); return dummy_el;}
+}
+
+void H_BeamParticle::emitGamma(const double gee, const double gq2) {
+	emitGamma(gee,gq2,0,2*PI);
+	return;
+}
+
+void H_BeamParticle::emitGamma(const double gee, const double gq2, const double phimin, const double phimax) {
+	/// @param gee = \f$ E_{\gamma} \f$ is the photon energy
+	/// @param gq2 = Q < 0 is virtuality of photon \f$ Q^{2} = E^{2}-\vec{k}^{2} \f$
+	/// @param phimin : lower bound for \f$ phi \f$
+	/// @param phimax : higher bound for \f$ phi \f$
+
+	if(gq2==0) { 
+		if(VERBOSE) cout<<"No virtuality : only energy has changed"<<endl;
+		setE(energy-gee);
+	    return;	
+	}
+
+	double m1 = mp;
+
+	double e1 = energy , e2 = energy - gee; // particle energy : before (1) / after (2)
+
+	double p1 = sqrt(pow(e1,2) - pow(m1,2)), p2 = sqrt(pow(e2,2) - pow(m1,2)); // particle momentum : before (1) / after (2)
+	double q2min = pow(gee,2) - pow(p1+p2,2); // lower bound from kinematics E^2 - (p1 + p2)^2
+	double q2max = -2 * pow(m1*gee/(p1+p2),2) * (1 + (pow(e1,2) + pow(e2,2) -pow(m1,2))/(e1*e2 + p1*p2) );
+			// upper bound from kinematics ; E^2 - (p1-p2)^2; is bad for numerical computations
+
+
+	// if q2min < q2 < q2max is NOT true, there will be mathematical problems (like cos(eta) > 1).
+	// so if q2 > q2max, we force q2 = q2max (-> cos(eta) = 1)
+	// and if q2 < q2min, we force q2 = q2min (-> cos(eta) = 1)
+	// BUT the user knows something was wrong with the value of "H_BeamParticle::isphysical"
+	const double q2 = (gq2 > q2max ) ? q2max : (gq2 < q2min) ? q2min : gq2;
+	
+	if( (gq2>q2max) || (gq2<q2min)) {
+		if(VERBOSE) cout<<"<H_BeamParticle> WARNING : Non physical particle ! Q2 (" << q2 << ") and E ("<<gee << ") are not compatible." << endl; 
+		isphysical = false; 
+	}
+
+	if(hasemitted) { cout<<"<H_BeamParticle> WARNING : particle has already emitted at least one gamma !"<<endl;}
+	hasemitted = true;
+	energy = energy - gee;
+	// gkk is k
+	double gkk = sqrt(pow(gee,2)-q2);
+	// eta is the angle between gamma and initial direction of the gamma-emitting particle
+        // ceta = cos(eta) and seta = sin(eta)
+
+	double ceta = sqrt( pow(mp/p1,2) + 1  ) * sqrt( q2/pow(gkk,2) + 1 ) - q2/(2*p1*gkk);
+	double seta = sqrt(1 - ceta*ceta); 
+	// theta is the angle between particle and beam
+        double theta = URAD*atan(seta/(BE/gkk - ceta));
+        double phi = phimin + gRandom->Uniform(phimax-phimin);
+        thx = thx + theta*cos(phi);
+        thy = thy - theta*sin(phi);
+
+	// caution : emitting a photon erases all known positions !
+	positions.clear();
+	addPosition(fx,thx,fy,thy,fs);
+	return;
+}
+
+void H_BeamParticle::doInelastic() {
+#ifdef _include_pythia_
+//	if(!gROOT->GetClass("TPythia6")) {
+//		gROOT->Reset();
+//	        gSystem->Load("libPythia6");
+//	        gSystem->Load("libEG");
+//	        gSystem->Load("libEGPythia6");
+//	}
+	
+	TPythia6 gen;
+	// select AB -> AX process 
+        gen.SetMSEL(0);
+        gen.SetMSUB(93,1);
+	// no showers/decays
+	gen.SetMSTP(111,0);
+	// no printouts
+	gen.SetMSTP(122,0);
+	gen.SetMSTU(12,0);
+	// generator initialization
+        gen.Initialize("CMS","p","p",14000);
+	// event generation
+	gen.GenerateEvent();
+	// list particles
+//	gen.Pylist(1);
+	thx = thx + URAD*atan(gen.GetP(5,1)/gen.GetP(5,3));
+	thy = thy + URAD*atan(gen.GetP(5,2)/gen.GetP(5,3));
+	energy = gen.GetP(5,4);
+	positions.clear();
+	addPosition(fx,thx,fy,thy,fs);
+#endif
+	return;
+}
+
+void H_BeamParticle::printProperties() const {
+	cout << " M   = " << getM()  << "GeV ";
+	cout << " Q   = " << getQ()  << "e";
+	cout << " fx  = " << getX()  << "m   ";
+ 	cout << " fy  = " << getY()  << "m   ";
+	cout << " thx = " << getTX() << "rad ";
+	cout << " thy = " << getTY() << "rad ";
+	cout << endl;
+	return;
+}
+
+/// The phase space vector is (x,x',y,y',E)
+/// [x] = [y] = meters
+/// [x'] = [y'] = 1  with x' = dx/ds = tan (thetaX)
+/// [E] = GeV
+const TMatrixD * H_BeamParticle::getV() const {
+	double vec[MDIM] = {fx/URAD, tan(thx/URAD), fy/URAD, tan(thy/URAD),energy};
+	TMatrixD * mat = new TMatrixD(1,MDIM,vec);
+	return mat;
+}	
+
+void H_BeamParticle::printV() const {
+	TMatrixD X(*getV());
+	cout << " x  = " << (X.GetMatrixArray())[0] << "m ";
+	cout << " x' = " << (X.GetMatrixArray())[1] << "  ";
+	cout << " y  = " << (X.GetMatrixArray())[2] << "m ";
+	cout << " y' = " << (X.GetMatrixArray())[3] << "  ";
+	cout << endl;
+	return;
+}
+
+void H_BeamParticle::propagate(const double position) {
+	/// @param position is the s coordinate in m to reach
+	/// Does not propagate if position is in the middle of an otics element of the beamline.
+        vector<TVectorD>::const_iterator position_i = positions.begin();
+	double l = 0.;
+	if(position != fs) { // avoid repeating the computation if already done at this position
+		if(position == (*position_i)[INDEX_S]) {
+			fs = position;
+			fx = (*position_i)[INDEX_X];
+			fy = (*position_i)[INDEX_Y];
+			thx= (*position_i)[INDEX_TX];
+			thy= (*position_i)[INDEX_TY]; 
+			return;
+		} else 
+        	for(position_i = positions.begin(); position_i < positions.end(); position_i++) {
+			if((*position_i)[INDEX_S]>=position) {
+				if(position_i==positions.begin()) {
+					if(VERBOSE) cout<<"<H_BeamParticle> ERROR : non reachable value"<<endl;
+					return;
+				}
+				l = (*position_i)[INDEX_S] - (*(position_i-1))[INDEX_S];
+				if(l==0) {
+					if(VERBOSE) cout<<"<H_BeamParticle> WARNING : no luck in choosing position, no propagation done"<<endl;
+					return;
+				}
+				fs = position;
+				fx = (*(position_i-1))[INDEX_X] + (position-(*(position_i-1))[INDEX_S])*((*position_i)[INDEX_X] - (*(position_i-1))[INDEX_X])/l;
+				fy = (*(position_i-1))[INDEX_Y] + (position-(*(position_i-1))[INDEX_S])*((*position_i)[INDEX_Y] - (*(position_i-1))[INDEX_Y])/l;
+				thx = (*(position_i-1))[INDEX_TX];
+				thy = (*(position_i-1))[INDEX_TY];
+				return;
+			}
+		}
+		position_i = positions.begin();
+		cout << "Desired position is : " << position << " & positions.begin() is " << (*position_i)[INDEX_S] << endl;
+		cout<<"<H_BeamParticle> ERROR : position not reachable"<<endl;	
+		return;
+	}
+}
+
+/// Caution : do not use this method (obsolete) !!!
+void H_BeamParticle::propagate(const H_AbstractBeamLine * beam, const H_OpticalElement * element) {
+	TMatrixD X(*getV());
+	X *= beam->getPartialMatrix(element);
+	fx = URAD*(X.GetMatrixArray())[0];
+	thx = URAD*atan((X.GetMatrixArray())[1]);
+	fy = URAD*(X.GetMatrixArray())[2];
+	thy = URAD*atan((X.GetMatrixArray())[3]);
+	return;
+}
+
+void H_BeamParticle::propagate(const H_AbstractBeamLine * beam, const string el_name) {
+	propagate(beam->getElement(el_name)->getS()+beam->getElement(el_name)->getLength());
+	return;
+}
+
+void H_BeamParticle::propagate(const H_AbstractBeamLine * beam) {
+	TMatrixD X(*getV());
+	X  *= beam->getBeamMatrix();
+	fx  = URAD*(X.GetMatrixArray())[0];
+	thx = URAD*atan((X.GetMatrixArray())[1]);
+	fy  = URAD*(X.GetMatrixArray())[2];
+	thy = URAD*atan((X.GetMatrixArray())[3]);
+	return;
+}
+
+void H_BeamParticle::showPositions() const{
+	vector<TVectorD>::const_iterator position_i;
+	TVectorD temp_vec(LENGTH_VEC);
+
+	for(position_i = positions.begin(); position_i < positions.end(); position_i++) {
+		cout << "Vector (x,y,s) = (" << (*position_i)[INDEX_X] << ", " << (*position_i)[INDEX_Y] << ", " << (*position_i)[INDEX_S] << "). " << endl;
+	}
+	return ;
+}
+
+TGraph * H_BeamParticle::getPath(const int x_or_y, const int color) const{
+        /// @param x_or_y = 0(1) draws the x(y) component;
+
+        const int N = (int) positions.size();
+		int mycolor = color;
+        if(N<2) cout<<"<H_BeamParticle> WARNING : particle positions not calculated : please run computePath"<<endl; 
+        double * s = new double[N], * graph = new double[N];
+
+        int index;
+        if(x_or_y==0) {index = INDEX_X;} else {index = INDEX_Y;}
+
+        vector<TVectorD>::const_iterator position_i;
+        for(position_i = positions.begin(); position_i < positions.end(); position_i++) {
+                graph[(int)(position_i-positions.begin())] = (*position_i)[index];
+                s[(int)(position_i-positions.begin())] = (*position_i)[INDEX_S];
+        }
+
+        TGraph * ppath = new TGraph(N,s,graph);
+        ppath->SetLineColor(mycolor);
+	delete [] s;
+	delete [] graph;
+        return ppath;
+}
+
+void H_BeamParticle::computePath(const H_AbstractBeamLine * beam) {
+	computePath(beam,true);
+}
+
+// should be removed later, to keep only computePath(const H_AbstractBeamLine & , const bool)
+void H_BeamParticle::computePath(const H_AbstractBeamLine * beam, const bool NonLinear) {
+	TMatrixD temp_mat(MDIM,MDIM);
+	double temp_x, temp_y, temp_s, temp_tx, temp_ty;
+
+	temp_x = (positions.front())[INDEX_X];
+        temp_tx = (positions.front())[INDEX_TX];
+        temp_y = (positions.front())[INDEX_Y];
+        temp_ty = (positions.front())[INDEX_TY];
+        temp_s = (positions.front())[INDEX_S];
+
+		double vec[MDIM] = {temp_x/URAD, tan(temp_tx/URAD), temp_y/URAD, tan(temp_ty/URAD),energy,1};
+
+		extern bool relative_energy;
+		if(relative_energy) {
+        	vec[4] = energy-BE;
+		} else {
+        	vec[4] = energy;
+		}
+
+	TMatrixD mat(1,MDIM,vec);
+
+	const int N =beam->getNumberOfElements();
+	double xys[LENGTH_VEC];
+
+	double energy_loss = NonLinear?BE-energy:0;
+
+	for (int i=0; i<N; i++) {
+		const unsigned pos = i;
+		if(fs < beam->getElement(pos)->getS() && fs > beam->getElement(pos-1)->getS()) {
+			if(beam->getElement(pos-1)->getType()!=DRIFT) { 
+				cout<<"Path starts inside element "<<beam->getElement(pos-1)->getName()<<endl;
+			} else { 
+				cout<<"Path starts inside unnamed drift "<<endl;
+			}
+			H_OpticalElement* temp_el = beam->getElement(pos-1)->clone();
+			temp_el->setS(fs);
+			temp_el->setLength(beam->getElement(pos)->getS() - fs);
+			mat[0][0] = mat[0][0] - temp_el->getX();
+			mat[0][1] = mat[0][1] - tan(temp_el->getTX());
+			mat[0][2] = mat[0][2] - temp_el->getY();
+			mat[0][3] = mat[0][3] - tan(temp_el->getTY());
+			mat *= temp_el->getMatrix(energy_loss,mp,qp);
+			mat[0][0] = mat[0][0] + temp_el->getX();
+			mat[0][1] = mat[0][1] + tan(temp_el->getTX());
+			mat[0][2] = mat[0][2] + temp_el->getY();
+			mat[0][3] = mat[0][3] + tan(temp_el->getTY());
+			xys[0] = mat.GetMatrixArray()[0]*URAD;
+			xys[1] = atan(mat.GetMatrixArray()[1])*URAD;
+			xys[2] = mat.GetMatrixArray()[2]*URAD;
+			xys[3] = atan(mat.GetMatrixArray()[3])*URAD;
+			xys[4] = temp_el->getS()+temp_el->getLength();
+			addPosition(xys[0],xys[1],xys[2],xys[3],xys[4]);
+			if (temp_el) delete temp_el;
+		} 
+		if(fs <= beam->getElement(pos)->getS()) {
+			mat[0][0] = mat[0][0] - beam->getElement(pos)->getX();
+			mat[0][1] = mat[0][1] - tan(beam->getElement(pos)->getTX()/URAD)*URAD;
+			mat[0][2] = mat[0][2] - beam->getElement(pos)->getY();
+			mat[0][3] = mat[0][3] - tan(beam->getElement(pos)->getTY()/URAD)*URAD;
+			mat *= beam->getElement(pos)->getMatrix(energy_loss,mp,qp);
+			mat[0][0] = mat[0][0] + beam->getElement(pos)->getX();
+			mat[0][1] = mat[0][1] + tan(beam->getElement(pos)->getTX()/URAD)*URAD;
+			mat[0][2] = mat[0][2] + beam->getElement(pos)->getY();
+			mat[0][3] = mat[0][3] + tan(beam->getElement(pos)->getTY()/URAD)*URAD;
+			xys[0] = mat.GetMatrixArray()[0]*URAD;
+			xys[1] = atan(mat.GetMatrixArray()[1])*URAD;
+			xys[2] = mat.GetMatrixArray()[2]*URAD;
+			xys[3] = atan(mat.GetMatrixArray()[3])*URAD;
+			xys[4] = beam->getElement(pos)->getS()+beam->getElement(pos)->getLength();
+			addPosition(xys[0],xys[1],xys[2],xys[3],xys[4]);
+		}
+	}
+}
+
+// part about non-ip particle is not ready yet. use the above method in the meantime
+void H_BeamParticle::computePath(const H_AbstractBeamLine & beam, const bool NonLinear) {
+	TMatrixD temp_mat(MDIM,MDIM);
+	double temp_x, temp_y, temp_s, temp_tx, temp_ty;
+
+	temp_x = (positions.front())[INDEX_X];
+        temp_tx = (positions.front())[INDEX_TX];
+        temp_y = (positions.front())[INDEX_Y];
+        temp_ty = (positions.front())[INDEX_TY];
+        temp_s = (positions.front())[INDEX_S];
+
+		double vec[MDIM] = {temp_x/URAD, tan(temp_tx/URAD), temp_y/URAD, tan(temp_ty/URAD),energy,1};
+
+		extern bool relative_energy;
+		if(relative_energy) {
+        	vec[4] = energy-BE;
+		} else {
+        	vec[4] = energy;
+		}
+
+	TMatrixD mat(1,MDIM,vec);
+
+	const int N =beam.getNumberOfElements();
+	double xys[LENGTH_VEC];
+
+	double energy_loss = NonLinear?BE-energy:0;
+
+	// modify here to allow starting at non-IP positions
+	// s is distance to IP
+	// initial position is already in positions vector ?
+	for (int i=0; i<N; i++) {
+		const unsigned pos = i;
+		// if we are inside an element, we should start by adding the action
+		// of the rest of this element
+		if(pos > 0 && fs < beam.getElement(pos)->getS() && fs > beam.getElement(pos-1)->getS()) {
+			cout<<"Path starts inside element "<<beam.getElement(pos-1)->getName()<<endl;
+			H_OpticalElement* temp_el = new H_OpticalElement(*(beam.getElement(pos-1)));
+			temp_el->setS(fs);
+			temp_el->setLength(beam.getElement(pos)->getS() - fs);
+			mat[0][0] = mat[0][0] - temp_el->getX();
+			mat[0][1] = mat[0][1] - tan(temp_el->getTX());
+			mat[0][2] = mat[0][2] - temp_el->getY();
+			mat[0][3] = mat[0][3] - tan(temp_el->getTY());
+			mat *= temp_el->getMatrix(energy_loss,mp,qp);
+			mat[0][0] = mat[0][0] + temp_el->getX();
+			mat[0][1] = mat[0][1] + tan(temp_el->getTX());
+			mat[0][2] = mat[0][2] + temp_el->getY();
+			mat[0][3] = mat[0][3] + tan(temp_el->getTY());
+		} else if(fs >= beam.getElement(pos)->getS()) {
+			mat[0][0] = mat[0][0] - beam.getElement(pos)->getX();
+			mat[0][1] = mat[0][1] - tan(beam.getElement(pos)->getTX());
+			mat[0][2] = mat[0][2] - beam.getElement(pos)->getY();
+			mat[0][3] = mat[0][3] - tan(beam.getElement(pos)->getTY());
+			mat *= beam.getElement(pos)->getMatrix(energy_loss,mp,qp);
+			mat[0][0] = mat[0][0] + beam.getElement(pos)->getX();
+			mat[0][1] = mat[0][1] + tan(beam.getElement(pos)->getTX());
+			mat[0][2] = mat[0][2] + beam.getElement(pos)->getY();
+			mat[0][3] = mat[0][3] + tan(beam.getElement(pos)->getTY());
+		}
+		xys[0] = mat.GetMatrixArray()[0]*URAD;
+		xys[1] = atan(mat.GetMatrixArray()[1])*URAD;
+		xys[2] = mat.GetMatrixArray()[2]*URAD;
+		xys[3] = atan(mat.GetMatrixArray()[3])*URAD;
+		xys[4] = beam.getElement(pos)->getS()+beam.getElement(pos)->getLength();
+		addPosition(xys[0],xys[1],xys[2],xys[3],xys[4]);
+		fx = xys[0];
+		fy = xys[2];
+		thx = xys[1];
+		thy = xys[3];
+	}
+}
+
+void H_BeamParticle::resetPath() {
+	double temp_x, temp_y, temp_s, temp_tx, temp_ty;
+
+	temp_x = (positions.front())[INDEX_X];
+	temp_tx = (positions.front())[INDEX_TX];
+	temp_y = (positions.front())[INDEX_Y];
+	temp_ty = (positions.front())[INDEX_TY];
+	temp_s = (positions.front())[INDEX_S];
+	positions.clear();
+	addPosition(temp_x,temp_tx,temp_y,temp_ty,temp_s);
+}
+
+const TVectorD * H_BeamParticle::getPosition(const int element_position) const {
+ 	const int N = (element_position<0)?0:(( ((unsigned int) element_position)>positions.size()-1)?positions.size()-1:element_position);
+ 	return &(*(positions.begin()+N));// same as "return &positions[N];", but more efficient
+}
Index: /trunk/Utilities/Hector/src/H_CircularAperture.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_CircularAperture.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_CircularAperture.cc	(revision 3)
@@ -0,0 +1,40 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_CircularAperture.cc
+/// \brief Defines the circular aperture of beamline elements.
+
+// C++ #includes
+#include <iostream>
+
+// C #includes
+#include <cmath> // needed for fabs and log
+
+// local #includes
+#include "H_CircularAperture.h"
+using namespace std;
+
+/// Circular apertures
+H_CircularAperture::H_CircularAperture(const float r, const float posx, const float posy) :H_EllipticAperture(r,r,posx,posy) { 
+        /// @param r is the radius of the circular shape
+        /// @param posx, posy are the (x,y) coordinates of the center of the circle
+	type= CIRCULAR; 
+}
+
+H_CircularAperture* H_CircularAperture::clone() const {
+	return new H_CircularAperture(x1,fx,fy);
+}
+
+void H_CircularAperture::printProperties() const {
+        cout << "Aperture shape:" << getTypeString() << ", aperture radius : " << x1 << endl;
+        cout << " \t Center : " << fx << "," << fy << endl;
+        return;
+}
Index: /trunk/Utilities/Hector/src/H_Dipole.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_Dipole.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_Dipole.cc	(revision 3)
@@ -0,0 +1,41 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Dipole.cc
+/// \brief Class aiming at simulating LHC beam dipoles
+
+//local includes
+#include "H_Dipole.h"
+
+void H_Dipole::init() {
+	// needed for call from R- and S-Dipoles constructor
+	// must be in public section
+	    element_mat.ResizeTo(MDIM,MDIM);
+		setTypeString();
+		if (fk !=0 ) setMatrix(0,MP,QP);
+	return;
+}
+
+void H_Dipole::printProperties() const {
+	cout << typestring;
+	cout << name;
+	cout<<"\t at s = "<< fs;
+	cout<<"\t length = "<< element_length;
+	cout<<"\t k0 = "<<fk;
+	cout<<endl;
+        if(element_aperture->getType()!=NONE) {
+        	cout <<"\t aperture type = " << element_aperture->getTypeString();
+                element_aperture->printProperties();
+	}
+
+	if(element_length<0)  { if(VERBOSE) cout<<"<H_Dipole> ERROR : Interpenetration of elements !"<<endl; }
+	if(element_length==0) { if(VERBOSE) cout<<"<H_Dipole> WARNING : 0-length "<< name << " !" << endl; }
+}
Index: /trunk/Utilities/Hector/src/H_Drift.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_Drift.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_Drift.cc	(revision 3)
@@ -0,0 +1,56 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Drift.cc
+/// \brief Class aiming at simulating LHC beam drift.
+
+// local includes
+#include "H_Drift.h"
+#include "H_TransportMatrices.h"
+
+
+void H_Drift::init() {
+	// must be in public section
+	element_mat.ResizeTo(MDIM,MDIM);
+	setTypeString();
+	setMatrix(0,MP,QP);
+	return;
+}
+
+void H_Drift::printProperties() const {
+	cout << typestring << name;
+	cout << "\t\t at s = " << fs;
+	cout << "\t length = " << element_length;
+	cout<<endl;
+	if(element_aperture->getType()!=NONE) {
+		cout <<"\t aperture type = " << element_aperture->getTypeString();
+                element_aperture->printProperties();
+        }
+	if(element_length<0)  { if(VERBOSE) cout<<"<H_Drift> ERROR : Interpenetration of elements !"<<endl; }
+	if(element_length==0) { if(VERBOSE) cout<<"<H_Drift> WARNING : 0-length "<< name << " !" << endl; }
+}
+
+void H_Drift::setMatrix(const float eloss, const float p_mass, const float p_charge) {
+	element_mat = driftmat(element_length);
+	return ;
+}
+
+H_Drift* H_Drift::clone() const {
+	H_Drift* temp_drift = new H_Drift(name,fs,element_length);
+	temp_drift->setX(xpos);
+	temp_drift->setY(ypos);
+	temp_drift->setTX(txpos);
+	temp_drift->setTY(typos);
+	temp_drift->setBetaX(betax);
+	temp_drift->setBetaY(betay); 
+	return temp_drift;
+}
+
Index: /trunk/Utilities/Hector/src/H_EllipticAperture.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_EllipticAperture.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_EllipticAperture.cc	(revision 3)
@@ -0,0 +1,54 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_EllipticAperture.cc
+/// \brief Defines the elliptic aperture of beamline elements.
+
+// C++ #includes
+#include <iostream>
+
+// ROOT #includes
+#include "TEllipse.h"
+
+// local #includes
+#include "H_Parameters.h"
+#include "H_Aperture.h"
+#include "H_EllipticAperture.h"
+using namespace std;
+
+H_EllipticAperture::H_EllipticAperture(const float l, const float h, const float posx, const float posy) :H_Aperture(ELLIPTIC,l,h,0,0,posx,posy) {
+        /// @param l, h are the length and height of the elliptic shape
+        /// @param posx, posy are the (x,y) coordinates of the center of the ellipse
+}
+
+H_EllipticAperture* H_EllipticAperture::clone() const {
+	return new H_EllipticAperture(x1,x2,fx,fy);
+}
+
+bool H_EllipticAperture::isInside(const float x, const float y) const {
+        /// @param x, y are the (x,y) coordinates of the proton
+	return (((x-fx)/x1)*((x-fx)/x1) + ((y-fy)/x2)*((y-fy)/x2) < 1);
+}
+
+void H_EllipticAperture::draw(const float scale) const {
+	TEllipse* te = new TEllipse(fx*scale,fy*scale,x1*scale,x2*scale);
+	te->SetFillStyle(3003);
+	te->SetLineColor(39);
+	te->SetFillColor(39);
+	te->Draw("f");
+	return;
+}
+
+void H_EllipticAperture::printProperties() const {
+	cout<< "Aperture shape:" << getTypeString() << ", ellipse axes : "<<x1<<", "<<x2<<endl;
+	cout << " \t Center : " << fx << "," << fy << endl;
+	return;
+}
Index: /trunk/Utilities/Hector/src/H_HorizontalKicker.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_HorizontalKicker.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_HorizontalKicker.cc	(revision 3)
@@ -0,0 +1,44 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_HorizontalKicker.cc
+/// \brief Classes aiming at simulating horizontal kickers in beamline
+
+// fk [rad] for kickers !!!!
+
+// local #includes
+#include "H_HorizontalKicker.h"
+#include "H_TransportMatrices.h"
+
+int kickers_on = 0;
+
+void H_HorizontalKicker::setMatrix(const float eloss, const float p_mass, const float p_charge) {
+	extern int kickers_on;
+	if(kickers_on) {
+		element_mat = hkickmat(element_length,fk,eloss,p_mass,p_charge);
+	} else {
+		element_mat = driftmat(element_length);
+	}
+	return ;
+}
+
+H_HorizontalKicker* H_HorizontalKicker::clone() const {
+	H_HorizontalKicker* temp_kick = new H_HorizontalKicker(name,fs,fk,element_length);
+	temp_kick->setAperture(element_aperture);
+	temp_kick->setX(xpos);
+	temp_kick->setY(ypos);
+	temp_kick->setTX(txpos);
+	temp_kick->setTY(typos);
+	temp_kick->setBetaX(betax);
+	temp_kick->setBetaY(betay);
+	return temp_kick;
+}
+
Index: /trunk/Utilities/Hector/src/H_HorizontalQuadrupole.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_HorizontalQuadrupole.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_HorizontalQuadrupole.cc	(revision 3)
@@ -0,0 +1,38 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_HorizontalQuadrupole.cc
+/// \brief Classes aiming at simulating horizontal quadrupoles in beamline
+
+// local #includes
+#include "H_HorizontalQuadrupole.h"
+
+void H_HorizontalQuadrupole::setMatrix(const float eloss, const float p_mass, const float p_charge) {
+	if (fk>0)  { if(VERBOSE) cout<<"<H_HorizontalQuadrupole> ERROR : k1 should be < 0 (" << name << ")!"<<endl; }
+		if (fk !=0 ) element_mat = hquadmat(element_length,fk,eloss, p_mass, p_charge);
+		else  {
+			element_mat = driftmat(element_length);
+			if(VERBOSE) cout<<"<H_HorizontalQuadrupole> WARNING : k1= 0 ; drift-like quadrupole (" << name << ") !" << endl;
+   		}
+	return ;
+}
+
+H_HorizontalQuadrupole* H_HorizontalQuadrupole::clone() const {
+	H_HorizontalQuadrupole* temp_quad = new H_HorizontalQuadrupole(name,fs,fk,element_length);
+	temp_quad->setAperture(element_aperture);
+	temp_quad->setX(xpos);
+	temp_quad->setY(ypos);
+	temp_quad->setTX(txpos);
+	temp_quad->setTY(typos);
+	temp_quad->setBetaX(betax);
+	temp_quad->setBetaY(betay);
+	return temp_quad;
+}
Index: /trunk/Utilities/Hector/src/H_Kicker.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_Kicker.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_Kicker.cc	(revision 3)
@@ -0,0 +1,43 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Kicker.cc
+/// \brief Classes aiming at simulating kickers in LHC beamline.
+
+// local #includes
+#include "H_OpticalElement.h"
+#include "H_Kicker.h"
+
+void H_Kicker::init() {
+	// needed for call from H- and V-Kickers constructor
+	// must be in public section
+		setTypeString();
+		if (fk !=0 ) {
+			setMatrix(0,MP,QP); 
+		}
+	return;
+}
+
+void H_Kicker::printProperties() const {
+	cout << typestring;
+	cout << name;
+	cout<<"\t at s = "<< fs;
+	cout<<"\t length = "<< element_length;
+	cout<<"\t k0 = "<<fk;
+	cout<<endl;
+	if(element_aperture->getType()!=NONE) {
+		cout <<"\t aperture type = " << element_aperture->getTypeString();
+                element_aperture->printProperties();
+        }
+
+	if(element_length<0)  { if(VERBOSE) cout<<"<H_Kicker> ERROR : Interpenetration of elements !"<<endl; }
+	if(element_length==0) { if(VERBOSE) cout<<"<H_Kicker> WARNING : 0-length "<< name << " !" << endl; }
+}
Index: /trunk/Utilities/Hector/src/H_Marker.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_Marker.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_Marker.cc	(revision 3)
@@ -0,0 +1,50 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Marker.cc
+/// \brief Class defining a marker in the beamline (e.g. for interaction point)
+
+// local includes
+#include "H_Marker.h"
+#include "H_TransportMatrices.h"
+
+void H_Marker::init() {
+	// must be in public section
+	setTypeString();
+	setMatrix(0,MP,QP);
+	return;
+}
+
+void H_Marker::printProperties() const {
+	cout << typestring << name;
+	cout << "\t\t at s = " << fs << endl;
+	if(element_aperture->getType()!=NONE) {
+		cout <<"\t aperture type = " << element_aperture->getTypeString();
+                element_aperture->printProperties();
+        }
+}
+
+void H_Marker::setMatrix(const float eloss, const float p_mass, const float p_charge) {
+		element_mat = driftmat(0);
+	return ;
+}
+
+H_Marker* H_Marker::clone() const {
+	H_Marker* temp_mkr = new H_Marker(name,fs);
+	temp_mkr->setAperture(element_aperture);
+	temp_mkr->setX(xpos);
+	temp_mkr->setY(ypos);
+	temp_mkr->setTX(txpos);
+	temp_mkr->setTY(typos);
+	temp_mkr->setBetaX(betax);
+	temp_mkr->setBetaY(betay);
+	return temp_mkr;
+}
Index: /trunk/Utilities/Hector/src/H_OpticalElement.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_OpticalElement.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_OpticalElement.cc	(revision 3)
@@ -0,0 +1,297 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_OpticalElement.cc
+/// \brief Class aiming at describing any beam optical element.
+
+// c++ #includes
+#include <iostream>
+#include <string>
+
+// ROOT #includes
+#include "TPaveLabel.h"
+
+// local #includes
+#include "H_Parameters.h"
+#include "H_TransportMatrices.h"
+#include "H_Aperture.h"
+#include "H_OpticalElement.h"
+using namespace std;
+
+/// called by the constructors
+void H_OpticalElement::init(const string nameE, const int typeE, const double s, const double k, const double l) {
+	// this is called by the constructors
+	// must be in public section !
+	// xpos and ypos are vectors with n point. They define the aperture shape of the optical element.
+	name = nameE;
+	fs = s;
+ 	fk = k;
+	xpos = 0;
+	ypos = 0;
+	txpos = 0;
+	typos = 0;
+ 	element_length = l;
+ 	type = typeE;
+	element_mat.ResizeTo(MDIM,MDIM);
+ 	element_mat = driftmat(l);
+
+	// do NOT use setAperture for the initialisation ! there are protections there
+	
+	if(element_length<0)  { if(VERBOSE) cout<<"<H_OpticalElement> ERROR : Interpenetration of elements !"<<endl; }
+	if(element_length==0) { if(VERBOSE) cout<<"<H_OpticalElement> WARNING : 0-length element ! (" << name << ") " << " at " << fs << endl; }
+	betax =0;
+	betay =0;
+}
+
+H_OpticalElement::H_OpticalElement() : element_aperture(new H_Aperture()) {
+	init("",DRIFT,0.,0.,0.1);
+}
+
+H_OpticalElement::H_OpticalElement(const string nameE, const int typeE, const double s, const double k, const double l) : element_aperture(new H_Aperture()) {
+	init(nameE,typeE,s,k,l);
+}
+
+H_OpticalElement::H_OpticalElement(const string nameE, const int typeE, const double s, const double k, const double l, H_Aperture* the_app) : element_aperture(the_app->clone()) {
+	init(nameE,typeE,s,k,l);
+}
+
+H_OpticalElement::H_OpticalElement(const int typeE, const double s, const double k, const double l, H_Aperture* the_app) : element_aperture(the_app->clone()) {
+	init("",typeE,s,k,l);
+}
+
+H_OpticalElement::H_OpticalElement(const int typeE, const double s, const double k, const double l) : element_aperture(new H_Aperture()) {
+	init("",typeE,s,k,l);
+}
+
+H_OpticalElement::H_OpticalElement(const H_OpticalElement& el) {
+	fs = el.fs;
+	element_length = el.element_length;
+	fk = el.fk;
+	xpos = el.xpos;
+	ypos = el.ypos;
+	txpos = el.txpos;
+	typos = el.typos;
+	betax = el.betax;
+	betay = el.betay;
+	type = el.type;
+	name = el.name;
+	typestring = el.typestring;
+	element_mat.ResizeTo(MDIM,MDIM);
+	element_mat = el.element_mat;
+	element_aperture = el.element_aperture->clone();
+}
+
+H_OpticalElement& H_OpticalElement::operator=(const H_OpticalElement& el) {
+	if(this==&el) return *this;
+        fs = el.fs;
+        element_length = el.element_length;
+        fk = el.fk;
+        xpos = el.xpos;
+        ypos = el.ypos;
+		txpos = el.txpos;
+		typos = el.typos;
+        betax = el.betax;
+        betay = el.betay;
+        type = el.type;
+        name = el.name;
+        typestring = el.typestring;
+		element_mat.ResizeTo(MDIM,MDIM);
+        element_mat = el.element_mat;
+        element_aperture = el.element_aperture->clone();
+	return *this;
+}
+
+void H_OpticalElement::setAperture(const H_Aperture* ap) {
+	// do NOT use setAperture in your constructor, as element_aperture is not initialized
+	// this function do not take into account ap if ap=0
+	// do nothing if element_mat = ap
+		if (!ap) {cout << "<H_OpticalElement> Trying to set an empty pointer for the aperture ! Nothing done.\n"; return;}
+		if (element_aperture != ap) {
+			delete element_aperture;
+			element_aperture = ap->clone();
+		}
+	return;
+}
+
+void H_OpticalElement::printProperties() const {
+		cout << typestring;
+		cout << name;
+		cout <<"\t at s = " << fs;
+		cout <<"\t length = "<< element_length;
+		if(fk!=0) cout <<"\t strength = " << fk;
+		if(element_aperture->getType()!=NONE) { 
+			cout <<"\t aperture type = " << element_aperture->getTypeString();
+			element_aperture->printProperties();			
+		}
+	
+		cout<<endl;
+		if(element_length<0)  { if(VERBOSE) cout<<"<H_OpticalElement> ERROR : Interpenetration of elements !"<<endl; }
+		if(element_length==0) { if(VERBOSE) cout<<"<H_OpticalElement> WARNING : 0-length "<< typestring << " !" << endl; }
+
+ return;
+}
+
+void H_OpticalElement::showMatrix() const {
+	printMatrix(element_mat);
+	return;
+}
+
+void H_OpticalElement::drawAperture() const {
+	element_aperture->draw();
+	return;
+}
+
+TMatrix H_OpticalElement::getMatrix() {
+	setMatrix(0,MP,1);
+	return element_mat;
+}
+
+TMatrix H_OpticalElement::getMatrix(const float eloss, const float p_mass, const float p_charge) {
+	setMatrix(eloss,p_mass,p_charge);
+	return element_mat;
+}
+
+void H_OpticalElement::draw(const float meight, const float height) const{
+	/// @param meight is the minimal extend of the graph
+	/// @param height is the maximal extend of the graph
+	float x1 = getS();
+	float x2 = getS() + getLength();
+	float y1 = meight;
+	float y2 = height;
+	TPaveLabel* cur_box = new TPaveLabel(x1,y1,x2,y2,"");
+	cur_box->SetBorderSize(1);
+	cur_box->SetFillStyle(1001);
+	cur_box->SetFillColor((int)getType());
+	cur_box->Draw();
+}
+
+TVectorD H_OpticalElement::getHitPosition(TVectorD init_pos, double energy_loss, double mp, double qp) {
+	if(!element_length) {
+		// cout<<"O-length element ("<<getName()<<"), should not appear here !"<<endl;
+		return init_pos;
+	}
+	// some declarations
+	bool inside = false;
+	double vec[MDIM] = {init_pos[INDEX_X]/URAD,tan(init_pos[INDEX_TX]/URAD),init_pos[INDEX_Y]/URAD,tan(init_pos[INDEX_TY]/URAD),-energy_loss,1};
+	TMatrixD mat_init(1,MDIM,vec);
+	TMatrixD mat_min(1,MDIM,vec);
+	TMatrixD mat_max(1,MDIM,vec);
+	TMatrixD mat_stop(1,MDIM,vec);
+	H_OpticalElement* temp_el = clone();
+	// initialasing boundaries
+	double min_pos = 0;
+	double max_pos = element_length/2.;
+	double max_old = element_length/2.;
+	// number of iterations 
+	// (idea : fix precision instead of number of iterations + add security)
+	// (idea : interpolate between max and min and give the error)
+	const int N = 10;
+	// starting search loop
+	for(int i = 0; i < N; i++) {
+		// fixing position to be investigated 
+		temp_el->setLength(max_pos);
+		// initialising the vector at the initial vector + possible shift/tilt
+		mat_max[0][0] = mat_init[0][0] - temp_el->getX();
+		mat_max[0][1] = mat_init[0][1] - tan(temp_el->getTX());
+		mat_max[0][2] = mat_init[0][2] - temp_el->getY();
+		mat_max[0][3] = mat_init[0][3] - tan(temp_el->getTY());
+		// propagating
+		mat_max *= temp_el->getMatrix(energy_loss,mp,qp);
+		// compensating for the previously stated shifts/tilts
+		mat_max[0][0] = mat_max[0][0] + temp_el->getX();
+		mat_max[0][1] = mat_max[0][1] + tan(temp_el->getTX());
+		mat_max[0][2] = mat_max[0][2] + temp_el->getY();
+		mat_max[0][3] = mat_max[0][3] + tan(temp_el->getTY());
+		// fixing new boundaries 
+		if(temp_el->isInside(mat_max.GetMatrixArray()[0]*URAD,mat_max.GetMatrixArray()[2]*URAD)) {
+			max_old = max_pos;
+			max_pos = max_pos + (max_pos - min_pos)/2.;
+			min_pos = max_old;
+			inside = true;
+		} else {
+			max_pos = min_pos + (max_pos - min_pos)/2.;
+			inside = false;
+		}
+		// end of loop
+	}
+	// if it passes at the last iteration, choosing the other rangeÂ²
+	if(inside) min_pos = max_old;
+	// here the interpolation method : now we are sure that the intercept is between min_pos and max_pos
+	// getting vector at min_pos (for first boundary) :
+	bool precision_estimate = false;
+	if(precision_estimate) {
+		temp_el->setLength(min_pos);
+		mat_min[0][0] = mat_init[0][0] - temp_el->getX();
+		mat_min[0][1] = mat_init[0][1] - tan(temp_el->getTX());
+		mat_min[0][2] = mat_init[0][2] - temp_el->getY();
+		mat_min[0][3] = mat_init[0][3] - tan(temp_el->getTY());
+		mat_min *= temp_el->getMatrix(energy_loss,mp,qp);
+		mat_min[0][0] = mat_min[0][0] + temp_el->getX();
+   		mat_min[0][1] = mat_min[0][1] + tan(temp_el->getTX());
+ 	  	mat_min[0][2] = mat_min[0][2] + temp_el->getY();
+	    mat_min[0][3] = mat_min[0][3] + tan(temp_el->getTY());
+		mat_min[0][4] = min_pos + init_pos[4];
+		// getting vector at max_pos (for second boundary) :
+		temp_el->setLength(max_pos);
+	   	mat_max[0][0] = mat_init[0][0] - temp_el->getX();
+	    mat_max[0][1] = mat_init[0][1] - tan(temp_el->getTX());
+ 		mat_max[0][2] = mat_init[0][2] - temp_el->getY();
+ 	    mat_max[0][3] = mat_init[0][3] - tan(temp_el->getTY());
+ 	    mat_max *= temp_el->getMatrix(energy_loss,mp,qp);
+ 	    mat_max[0][0] = mat_max[0][0] + temp_el->getX();
+  	    mat_max[0][1] = mat_max[0][1] + tan(temp_el->getTX());
+  	    mat_max[0][2] = mat_max[0][2] + temp_el->getY();
+        mat_max[0][3] = mat_max[0][3] + tan(temp_el->getTY());
+		mat_max[0][4] = max_pos + init_pos[4];
+	}
+	// getting vector in the middle (for estimate) :
+	temp_el->setLength((max_pos+min_pos)/2.);
+    mat_stop[0][0] = mat_init[0][0] - temp_el->getX();
+    mat_stop[0][1] = mat_init[0][1] - tan(temp_el->getTX());
+    mat_stop[0][2] = mat_init[0][2] - temp_el->getY();
+    mat_stop[0][3] = mat_init[0][3] - tan(temp_el->getTY());
+    mat_stop *= temp_el->getMatrix(energy_loss,mp,qp);
+    mat_stop[0][0] = mat_stop[0][0] + temp_el->getX();
+    mat_stop[0][1] = mat_stop[0][1] + tan(temp_el->getTX());
+    mat_stop[0][2] = mat_stop[0][2] + temp_el->getY();
+    mat_stop[0][3] = mat_stop[0][3] + tan(temp_el->getTY());
+	mat_stop[0][4] = (max_pos+min_pos)/2. + init_pos[4];
+
+    double xys[LENGTH_VEC];
+    xys[INDEX_X]=  mat_stop[0][0]*URAD;
+    xys[INDEX_TX]= atan(mat_stop[0][1])*URAD;
+    xys[INDEX_Y]=  mat_stop[0][2]*URAD;
+    xys[INDEX_TY]= atan(mat_stop[0][3])*URAD;
+    xys[INDEX_S]=  mat_stop[0][4] ;
+    TVectorD temp_vec(LENGTH_VEC,xys);
+
+	if(precision_estimate) {
+		cout<<"--- Results and precision estimates ---"<<endl;
+		cout<<"\t Stopping element : "<<getName()<<endl;
+		cout<<"\t hit point s  : "<<mat_stop[0][4]<<" m +- "<<(mat_max[0][4]-mat_stop[0][4])*1000.<<" mm"<<endl;
+		cout<<"\t hit point x  : "<<mat_stop[0][0]*URAD;
+		cout<<" + "<<fabs(((mat_min[0][0]<mat_max[0][0])?(mat_max[0][0]-mat_stop[0][0])*URAD:(mat_min[0][0]-mat_stop[0][0])*URAD));
+		cout<<" - "<<fabs(((mat_min[0][0]<mat_max[0][0])?(mat_stop[0][0]-mat_min[0][0])*URAD:(mat_stop[0][0]-mat_max[0][0])*URAD))<<" Âµm"<<endl;
+		cout<<"\t hit point y  : "<<mat_stop[0][2]*URAD;
+        cout<<" + "<<fabs(((mat_min[0][0]<mat_max[0][2])?(mat_max[0][2]-mat_stop[0][2])*URAD:(mat_min[0][2]-mat_stop[0][2])*URAD));
+        cout<<" - "<<fabs(((mat_min[0][0]<mat_max[0][2])?(mat_stop[0][2]-mat_min[0][2])*URAD:(mat_stop[0][2]-mat_max[0][2])*URAD))<<" Âµm"<<endl;
+    	cout<<"\t hit point tx : "<<mat_stop[0][1]*URAD;
+        cout<<" + "<<fabs(((mat_min[0][0]<mat_max[0][1])?(mat_max[0][1]-mat_stop[0][1])*URAD:(mat_min[0][1]-mat_stop[0][1])*URAD));
+        cout<<" - "<<fabs(((mat_min[0][0]<mat_max[0][1])?(mat_stop[0][1]-mat_min[0][1])*URAD:(mat_stop[0][1]-mat_max[0][1])*URAD))<<" Âµrad"<<endl;
+		cout<<"\t hit point ty : "<<mat_stop[0][3]*URAD;
+        cout<<" + "<<fabs(((mat_min[0][0]<mat_max[0][3])?(mat_max[0][3]-mat_stop[0][3])*URAD:(mat_min[0][3]-mat_stop[0][3])*URAD));
+        cout<<" - "<<fabs(((mat_min[0][0]<mat_max[0][3])?(mat_stop[0][3]-mat_min[0][3])*URAD:(mat_stop[0][3]-mat_max[0][3])*URAD))<<" Âµrad"<<endl;
+
+	}
+
+	delete temp_el;
+	return temp_vec;
+}
Index: /trunk/Utilities/Hector/src/H_Parameters.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_Parameters.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_Parameters.cc	(revision 3)
@@ -0,0 +1,16 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+///\file H_Parameters.cc
+///\brief Class aiming at gathering all parameters that must be defined
+
+#include "H_Parameters.h"
+ //Needed for the compilator of H_Parameters into an object (.o) file
Index: /trunk/Utilities/Hector/src/H_Quadrupole.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_Quadrupole.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_Quadrupole.cc	(revision 3)
@@ -0,0 +1,40 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_Quadrupole.cc
+/// \brief Classes aiming at simulating LHC beam quadrupoles.
+
+#include "H_Quadrupole.h"
+
+void H_Quadrupole::init() {
+	// needed for call from H- and V-Quadrupoles constructor
+	// must be in public section
+		element_mat.ResizeTo(MDIM,MDIM);
+		setTypeString();
+		setMatrix(0,MP,QP);
+	return;
+}
+
+void H_Quadrupole::printProperties() const{
+	cout << typestring;
+	cout << name;
+	cout << "\t at s = " << fs;
+	cout << "\t length = " << element_length;
+	cout << "\t k1 = " << fk;
+	cout<<endl;
+        if(element_aperture->getType()!=NONE) {
+        	cout <<"\t aperture type = " << element_aperture->getTypeString();
+                element_aperture->printProperties();
+	}
+
+	if(element_length<0)  { if(VERBOSE) cout<<"<H_Quadrupole> ERROR : Interpenetration of elements !"<<endl; }
+	if(element_length==0) { if(VERBOSE) cout<<"<H_Quadrupole> WARNING : 0-length "<< typestring << " !" << endl; }
+}
Index: /trunk/Utilities/Hector/src/H_RecRPObject.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_RecRPObject.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_RecRPObject.cc	(revision 3)
@@ -0,0 +1,309 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+
+/// \file H_RecRPObject.cc
+/// \brief Class performing the reconstruction based on forward detector measurements
+///
+/// Units : angles [rad], distances [m], energies [GeV], c=[1].
+
+// local #includes
+#include "H_RecRPObject.h"
+#include "H_RomanPot.h"
+#include "H_BeamParticle.h"
+using namespace std;
+
+// reconstruction class for forward detectors.
+// Featuring the brand-new reco method from the 
+// louvain group !
+
+#define MEGA 1000000.
+
+H_RecRPObject::H_RecRPObject(): emin(0), emax(-1), x1(0), x2(0), y1(0), y2(0), s1(0), s2(0), 
+				txip(NOT_YET_COMPUTED), tyip(NOT_YET_COMPUTED), energy(NOT_YET_COMPUTED), q2(NOT_YET_COMPUTED), pt(NOT_YET_COMPUTED), 
+				thebeam(new H_AbstractBeamLine()),
+				f_1(new TF1("f_1","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				f_2(new TF1("f_2","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				g_1(new TF1("g_1","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				g_2(new TF1("g_2","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				d_1(new TF1("d_1","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				d_2(new TF1("d_2","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				k_1(new TF1("k_1","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				k_2(new TF1("k_2","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				l_1(new TF1("l_1","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				l_2(new TF1("l_2","[0] + [1]*x + [2]*x*x ",emin,emax)) 
+				{
+	// emax = -1; /* GeV */
+}
+
+H_RecRPObject::H_RecRPObject(float ss1, float ss2, H_AbstractBeamLine* beam) : emin(0), emax(-1), x1(0), x2(0), y1(0), y2(0), s1(ss1), s2(ss2), 
+				txip(NOT_YET_COMPUTED), tyip(NOT_YET_COMPUTED), energy(NOT_YET_COMPUTED), q2(NOT_YET_COMPUTED), pt(NOT_YET_COMPUTED), 
+				thebeam(beam),
+				f_1(new TF1("f_1","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				f_2(new TF1("f_2","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				g_1(new TF1("g_1","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				g_2(new TF1("g_2","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				d_1(new TF1("d_1","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				d_2(new TF1("d_2","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				k_1(new TF1("k_1","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				k_2(new TF1("k_2","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				l_1(new TF1("l_1","[0] + [1]*x + [2]*x*x ",emin,emax)), 
+				l_2(new TF1("l_2","[0] + [1]*x + [2]*x*x ",emin,emax))
+				{
+	if(ss1==ss2) cout<<"<H_RecRPObject> WARNING : detectors are on same position"<<endl;
+	// emax = -1; /* GeV */
+}
+
+void H_RecRPObject::initialize() {
+	// this method sets the functions that will be used for reco later
+	// it should be used only once per beamline after the energy range was fixed. 
+	// copying beamline and adding detectors
+	
+	if(emax<0) {
+		cout<<"<H_RecRPObject> ERROR : energy range has to be set first !"<<endl;
+		cout<<"<H_RecRPObject> Please run setERange() or computeERange()"<<endl;
+		cout<<"<H_RecRPObject> initialization aborted"<<endl;
+		return;
+	}
+
+	if(emax<emin) {
+		cout<<"<H_RecRPObject> ERROR : maximum energy lower than minimum !"<<endl;
+		cout<<"<H_RecRPObject> Please (re-)do setERange()"<<endl;
+		cout<<"<H_RecRPObject> initialization aborted"<<endl;
+		return;
+	}
+
+	H_AbstractBeamLine * b1 = thebeam->clone();
+	H_RomanPot * rp1 = new H_RomanPot("rp1",s1,0);
+	H_RomanPot * rp2 = new H_RomanPot("rp2",s2,0);
+	b1->add(rp1);
+	b1->add(rp2);
+
+	// fitting parameters
+	const int N = 20;
+	double e_i[N];
+	double f_1i[N], f_2i[N], g_1i[N], g_2i[N], d_1i[N], d_2i[N];
+	double k_1i[N], k_2i[N], l_1i[N], l_2i[N];
+	for(int i = 0; i < N; i++) {
+		e_i[i] = emin + i * (emax - emin)/((double)N-1);
+		// 
+		// the bug seems to be linked to the delete operator of the TMatrixT class in root.
+		// valgrind shows memory problems at that point.
+		// for unknwown reasons, copying the matrix gets around this bug.
+		// valgrind (related) ouptut :
+		//
+		// ==13029== Invalid read of size 4
+		// ==13029==    at 0x5E75DB6: H_RecRPObject::initialize() (in /home/jdf/GGamma/Hector/lib/libHector.so)
+		// ==13029==    by 0x804A2D8: intelligentreco_rpo(double, double, double, double, std::string, int) (H_IntelligentReco.cpp:314)
+		// ==13029==    by 0x804A937: main (H_IntelligentReco.cpp:542)
+		// ==13029==  Address 0x64AC740 is 80 bytes inside a block of size 144 free'd
+		// ==13029==    at 0x4021D18: operator delete[](void*) (vg_replace_malloc.c:256)
+		// ==13029==    by 0x5651F57: TMatrixT<float>::Delete_m(int, float*&) (in /home/jdf/root/5.12/lib/libMatrix.so)
+		// ==13029==    by 0x565CC5D: TMatrixT<float>::~TMatrixT() (in /home/jdf/root/5.12/lib/libMatrix.so)
+		// ==13029==    by 0x5E75D25: H_RecRPObject::initialize() (in /home/jdf/GGamma/Hector/lib/libHector.so)
+		//
+		//
+		TMatrix el_mattt(b1->getPartialMatrix("rp1",e_i[i],MP,QP));
+		const float *el_mat1 = el_mattt.GetMatrixArray();
+		// 
+		// conclusion : first line of el_mat1 is completely messed-up if it is taken directly from 
+		// the return of getpartialmatrix like this : 
+		// const float *el_mat1 = (b1->getPartialMatrix("rp1",e_i[i],MP,QP)).GetMatrixArray()
+		//
+		// long-term solution (apart noticing root staff) : replacing el_mat1[i] by the equivalent el_mattt(j,k)
+		// which is anyway more transparent for the reader.
+		//
+		f_1i[i] = el_mat1[0];
+		g_1i[i] = el_mat1[1*MDIM];
+		d_1i[i] = MEGA*el_mat1[4*MDIM];
+		k_1i[i] = el_mat1[2*MDIM+2];
+		l_1i[i] = el_mat1[3*MDIM+2];
+		const float* el_mat2 = (b1->getPartialMatrix("rp2",e_i[i],MP,QP).GetMatrixArray());
+		f_2i[i] = el_mat2[0];
+		g_2i[i] = el_mat2[1*MDIM];
+		d_2i[i] = MEGA*el_mat2[4*MDIM];
+		k_2i[i] = el_mat2[2*MDIM+2];
+		l_2i[i] = el_mat2[3*MDIM+2];
+	}
+	TGraph gf_1(N,e_i,f_1i);
+	TGraph gg_1(N,e_i,g_1i);
+	TGraph gd_1(N,e_i,d_1i);
+	TGraph gf_2(N,e_i,f_2i);
+	TGraph gg_2(N,e_i,g_2i);
+	TGraph gd_2(N,e_i,d_2i);
+	TGraph gk_1(N,e_i,k_1i);
+	TGraph gl_1(N,e_i,l_1i);
+	TGraph gk_2(N,e_i,k_2i);
+	TGraph gl_2(N,e_i,l_2i);
+
+    // functions get their final shape	
+	gf_1.Fit("f_1","Q");
+	gg_1.Fit("g_1","Q");
+	gd_1.Fit("d_1","Q");
+	gf_2.Fit("f_2","Q");
+	gg_2.Fit("g_2","Q");
+	gd_2.Fit("d_2","Q");
+	gk_1.Fit("k_1","Q");
+	gl_1.Fit("l_1","Q");
+	gk_2.Fit("k_2","Q");
+	gl_2.Fit("l_2","Q");
+
+	// cleaning the rest
+	delete b1;
+
+	// the end
+	return;
+}
+
+void H_RecRPObject::setDetPos(const float ss1, const float ss2) {
+	energy = NOT_YET_COMPUTED;
+	s1 = ss1;
+	s2 = ss2;
+	if(ss1==ss2) cout<<"<H_RecRPObject> WARNING : detectors are on same position"<<endl;
+	return;
+}
+
+void H_RecRPObject::setPositions(const float xx1, const float xx2, const float yy1, const float yy2) {
+	energy = NOT_YET_COMPUTED;
+	x1 = xx1;
+	x2 = xx2;
+	y1 = yy1;
+	y2 = yy2;
+	return;
+}
+
+void H_RecRPObject::setPosition_det1(const float xx1, const float yy1) {
+	energy = NOT_YET_COMPUTED;
+	x1 = xx1;
+	y1 = yy1;
+}
+
+void H_RecRPObject::setPosition_det2(const float xx2, const float yy2) {
+	energy = NOT_YET_COMPUTED;
+	x2 = xx2;
+	y2 = yy2;
+}
+
+void H_RecRPObject::setERange(const float eemin, const float eemax) {
+	energy = NOT_YET_COMPUTED;
+	emin = eemin;
+	emax = eemax;
+	f_1->SetRange(emin,emax);
+	f_2->SetRange(emin,emax);
+	g_1->SetRange(emin,emax);
+	g_2->SetRange(emin,emax);
+	d_1->SetRange(emin,emax);
+	d_2->SetRange(emin,emax);
+	k_1->SetRange(emin,emax);
+	k_2->SetRange(emin,emax);
+	l_1->SetRange(emin,emax);
+	l_2->SetRange(emin,emax);
+    return;
+}
+
+
+void H_RecRPObject::computeERange() {
+	// optional method to determine the energy range of the FIRST detector 
+	// in order to refine the fits and get maximum precision.
+	energy = NOT_YET_COMPUTED;
+	H_AbstractBeamLine * b1 = thebeam->clone();
+	H_RomanPot * rp1 = new H_RomanPot("rp1",s1,0);
+	b1->add(rp1);
+	float max = 1;
+	// number of energies to check 
+	const int N = 1000;
+	for(int i=0; i<N; i++) {
+		H_BeamParticle p;
+		p.setE(BE - (emin + i*(BE-emin)/((float)N)));
+		p.computePath(b1);
+		if(p.stopped(b1)) {
+			if(p.getStoppingElement()->getName()=="rp1") {
+				max = emin + i*(BE-emin)/((float)N);
+			}
+		}
+	}
+	cout<<"<H_RecRPObject> Valid energy losses run from 0 (default) to "<<max+20.<<" GeV"<<endl;
+	setERange(0,max+20.);
+	delete b1;
+	return;
+}
+
+void H_RecRPObject::computeAll() {
+	// The big game :
+	// computing E, tx, ty, Q2 and Pt and filling the variables.
+	//
+	// The root TF1 class features nice bugs, which explains the
+	// seemingly-dumb structures happening sometimes here as
+	// workarounds for these bugs. The overall thing works very
+	// well but will be cleaned later anyway.
+
+	if(energy!=NOT_YET_COMPUTED) {
+		cout<<"<H_RecRPObject> already computed variables, skipping ..."<<endl;
+		return;
+	}
+
+	TF1 par0("par0","[0]",emin,emax);
+	par0.SetParameter(0,-x1);
+	TF1 par2("par2","[0]",emin,emax);
+	par2.SetParameter(0,-y1);
+	TF1 par1("par1","[0]",emin,emax);
+	par1.SetParameter(0,-x2);
+	TF1 par3("par3","[0]",emin,emax);
+	par3.SetParameter(0,-y2);
+
+	// angle compensating method :
+	TF1 xx_E("xx_E","(g_2*(par0-d_1*x)-g_1*(par1-d_2*x))/(f_2*g_1-f_1*g_2)",emin,emax);
+	TF1 yy_E("yy_E","(par2*l_2 - par3*l_1) / (k_2*l_1 - k_1*l_2)",emin,emax);
+	TF1 xp_E("xp_E","(f_2*(par0-d_1*x)-f_1*(par1-d_2*x))/(g_2*f_1-g_1*f_2)",emin,emax);
+	TF1 yp_E("yp_E","(par2*k_2-par3*k_1)/(l_2*k_1-l_1*k_2)",emin,emax);
+	// it is possible to refine study using y info, but effect was not tested.	
+	// TF1 p_xy_E("p_xy_E","(-xx_E*xx_E-yy_E*yy_E)",emin,emax);
+	TF1 p_xy_E("p_xy_E","(-xx_E*xx_E)",emin,emax);
+
+	energy = p_xy_E.GetMaximumX(emin,emax);
+	txip = xp_E.Eval(energy);
+	tyip = yp_E.Eval(energy);
+	pt = sqrt(BE*(BE-energy)*(txip*txip+tyip*tyip)/(MEGA*MEGA));
+
+	return;
+}
+
+float H_RecRPObject::getE(int a) {
+// put for backward compatibility
+        if(energy==NOT_YET_COMPUTED) { computeAll(); };
+        return energy;
+}  // to be removed !!!!!
+
+float H_RecRPObject::getE() {
+	if(energy==NOT_YET_COMPUTED) { computeAll(); };
+	return energy;
+}
+
+float H_RecRPObject::getTX() {
+	if(energy==NOT_YET_COMPUTED) { computeAll(); };
+	return txip;
+}
+
+float H_RecRPObject::getTY() {
+	if(energy==NOT_YET_COMPUTED) { computeAll(); };
+	return tyip;
+}
+
+float H_RecRPObject::getQ2() {
+	if(energy==NOT_YET_COMPUTED) { computeAll(); };
+	cout<<"<H_RecRPObject::getQ2> Not implemented yet"<<endl;
+	return 0;
+}
+
+float H_RecRPObject::getPt() {
+	if(energy==NOT_YET_COMPUTED) { computeAll(); };
+	return pt;
+}
Index: /trunk/Utilities/Hector/src/H_RectEllipticAperture.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_RectEllipticAperture.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_RectEllipticAperture.cc	(revision 3)
@@ -0,0 +1,133 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_RectEllipticAperture.cc
+/// \brief Defines the Rect-Elliptic aperture of beamline elements.
+
+// C++ #includes
+#include <iostream>
+
+// C #includes
+#include <cmath> // needed for fabs
+
+// ROOT #includes
+#include "TPolyLine.h"
+
+// local #includes
+#include "H_RectEllipticAperture.h"
+using namespace std;
+
+H_RectEllipticAperture::H_RectEllipticAperture(const float l, const float h, const float L, const float H, const float posx, const float posy) :H_Aperture(RECTELLIPSE,((l==0)?L:l),((h==0)?H:h),L,H,posx,posy) {
+	/// @param l, h, L, H are the geometrical parameters of the rect-ellipse shape
+	/// @param posx, posy defines the (x,y) of the center of the shape
+	type= RECTELLIPSE;
+}
+
+H_RectEllipticAperture* H_RectEllipticAperture::clone() const {
+	return new H_RectEllipticAperture(x1,x2,x3,x4,fx,fy);
+}
+
+
+TPolyLine * rectellipse(const float a_e = 2, const float b_e = 1, const float a_r = 1, const float b_r = 2, const float center_x = 0, const float center_y =0) {
+        const int n = 20;  // number of points per segment
+        const int N = 4*n; // there are 4 segments
+        float x[N+1], y[N+1];
+
+   if(a_e>a_r) {
+        // a rectellipse has 4 segments
+        // 1) upper one
+        for (int i=0; i<n; i++) {
+                x[i] = -a_r + i*(2*a_r)/(float)n;
+                y[i] =  b_e * sqrt(1-pow(x[i]/a_e,2));
+        }
+
+        // 2) right vertical segment
+        // upper right corner
+        const float y2 = b_e * sqrt(1-pow(a_r/a_e,2));
+        // lower right corner
+        const float y3 = -b_e * sqrt(1-pow(a_r/a_e,2));
+        for (int i=n; i<2*n; i++) {
+                x[i] = a_r;
+                y[i] = y2 - (i-n)*(2*y2)/(float)n;
+        }
+
+        // 3) lower side
+        for (int i=2*n; i<3*n; i++) {
+                x[i] = a_r - (i-2*n)*(2*a_r)/(float)n;
+                y[i] = -b_e * sqrt(1-pow(x[i]/a_e,2));
+        }
+
+        // 4) left vertical segment
+        // lower left corner
+        const float y4 = y3;
+        for (int i=3*n; i<4*n; i++) {
+                x[i] = -a_r;
+                y[i] = y4 + (i-3*n)*(2*y2)/(float)n;
+        }
+   } else {
+	// 1) upper one : flat
+	const float x1 = -a_e * sqrt(1-pow(b_r/b_e,2));
+	const float x2 = -x1;
+	for (int i=0; i<n; i++) {
+		y[i] = b_r;
+		x[i] = x1 + i * (x2-x1)/(float)n;
+	}
+	
+	// 2) right curved border
+	for (int i=n; i<2*n; i++) {
+		y[i] = b_r - (i-n) * (2*b_r)/(float)n;
+		x[i] = a_e * sqrt(1-pow(y[i]/b_e,2));
+	}
+
+	// 3) lower side : flat
+	for (int i=2*n; i<3*n; i++) {
+		y[i] = -b_r;
+		x[i] = x2 - (i-2*n) * (2*x2)/(float)n;
+	}
+	
+	// 4) left curved border
+	for (int i=3*n; i<4*n; i++) {
+		y[i] = -b_r + (i-3*n) * (2*b_r)/(float)n;
+		x[i] = -a_e * sqrt(1-pow(y[i]/b_e,2));
+	}
+   }
+
+	// closing the polyline
+        x[N] = x[0];
+        y[N] = y[0];
+
+	// shifting the center
+        for (int i=0; i<N+1; i++) {
+                x[i] += center_x;
+                y[i] += center_y;
+        }
+
+        return new TPolyLine(N+1,x,y);
+}
+
+
+void H_RectEllipticAperture::draw(const float scale) const {
+	TPolyLine * re = rectellipse(x3*scale, x4*scale, x1*scale, x2*scale, fx*scale, fy*scale);
+	re->SetLineColor(39);
+	re->SetLineWidth(2);
+	re->Draw("l");
+	return;
+}
+
+bool H_RectEllipticAperture::isInside(const float x, const float y) const {
+	return((fabs(fx-x)<x1)&&(fabs(fy-y)<x2)&&(((x-fx)/x3)*((x-fx)/x3)+((y-fy)/x4)*((y-fy)/x4)<1));
+}
+
+void H_RectEllipticAperture::printProperties() const {
+	cout << "Aperture shape:" << getTypeString() << ", parameters " <<x1<<", "<<x2<<", "<<x3<<", "<<x4<< endl;
+	cout << " \t Center : "<<fx<<", "<<fy<<endl;
+	return;
+}
Index: /trunk/Utilities/Hector/src/H_RectangularAperture.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_RectangularAperture.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_RectangularAperture.cc	(revision 3)
@@ -0,0 +1,54 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_RectangularAperture.cc
+/// \brief Defines the rectangular aperture of beamline elements.
+
+// C++ #includes
+#include <iostream>
+
+// C #includes
+#include <cmath> // needed for fabs
+
+// ROOT #includes
+#include "TPave.h"
+
+// local #includes
+#include "H_RectangularAperture.h"
+using namespace std;
+
+H_RectangularAperture::H_RectangularAperture(const float l, const float h, const float posx, const float posy) :H_Aperture(RECTANGULAR,l,h,0,0,posx,posy) {
+	/// @param l, h are the length and height of the rectangular shape
+	/// @param posx, posy are the (x,y) coordinates of the center of the rectangular shape
+}
+
+H_RectangularAperture* H_RectangularAperture::clone() const {
+	return new H_RectangularAperture(x1,x2,fx,fy);
+}
+
+bool H_RectangularAperture::isInside(const float x, const float y) const {
+	/// @param x, y are the (x,y) coordinates of the proton, in [m]
+	return (fabs(x-fx)<x1&&fabs(y-fy)<x2);
+}
+
+void H_RectangularAperture::draw(const float scale) const {
+	TPave* tp = new TPave((fx-x1)*scale,(fy-x2)*scale,(fx+x1)*scale,(fy+x2)*scale,1);
+	tp->SetFillStyle(3003);
+	tp->SetLineColor(2);
+	tp->SetFillColor(2);
+	tp->Draw();
+	return;
+}
+void H_RectangularAperture::printProperties() const {
+	cout << "Aperture shape:" << getTypeString() << ", rectangle Sides : "<<x1<<", "<<x2<<endl;
+	cout << " \t Center : " << fx << "," << fy << endl;
+	return;
+}
Index: /trunk/Utilities/Hector/src/H_RectangularCollimator.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_RectangularCollimator.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_RectangularCollimator.cc	(revision 3)
@@ -0,0 +1,68 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_RectangularCollimator.cc
+/// \brief R-Collimators for the LHC beamline.
+
+// local #includes
+#include "H_RectangularCollimator.h"
+#include "H_TransportMatrices.h"
+
+void H_RectangularCollimator::init() {
+	// must be in public section
+		setTypeString();
+		setMatrix(0,MP,QP);
+	return;
+}
+
+H_RectangularCollimator::H_RectangularCollimator(const double s, const double l) :H_Drift(s,l){
+	type = RCOLLIMATOR;
+	init();
+	return;
+}
+
+H_RectangularCollimator::H_RectangularCollimator(const string nameE, const double s, const double l) :H_Drift(nameE,s,l){
+	type = RCOLLIMATOR;
+	init();
+	return;
+}
+
+void H_RectangularCollimator::printProperties() const {
+	cout << typestring << name;
+	cout << "\t\t at s = " << fs;
+	cout << "\t length = " << element_length;
+	cout<<endl;
+	if(element_aperture->getType()!=NONE) {
+        	cout <<"\t aperture type = " << element_aperture->getTypeString();
+                	element_aperture->printProperties();
+	}
+
+	if(element_length<0)  { if(VERBOSE) cout<<"<H_RectangularCollimator> ERROR : Interpenetration of elements !"<<endl; }
+	if(element_length==0) { if(VERBOSE) cout<<"<H_RectangularCollimator> WARNING : 0-length "<< name << " !" << endl; }
+}
+
+void H_RectangularCollimator::setMatrix(const float eloss, const float p_mass, const float p_charge) {
+	element_mat = driftmat(element_length);
+	return ;
+}
+
+H_RectangularCollimator* H_RectangularCollimator::clone() const {
+	H_RectangularCollimator* temp_coll = new H_RectangularCollimator(name,fs,element_length);
+	temp_coll->setAperture(element_aperture);
+	temp_coll->setX(xpos);
+	temp_coll->setY(ypos);
+	temp_coll->setTX(txpos);
+	temp_coll->setTY(typos);
+	temp_coll->setBetaX(betax);
+	temp_coll->setBetaY(betay);
+	return temp_coll;
+}
+
Index: /trunk/Utilities/Hector/src/H_RectangularDipole.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_RectangularDipole.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_RectangularDipole.cc	(revision 3)
@@ -0,0 +1,38 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_RectangularDipole.cc
+/// \brief Classes aiming at simulating LHC beam rectangular dipoles
+
+#include "H_RectangularDipole.h"
+#include "H_TransportMatrices.h"
+
+void H_RectangularDipole::setMatrix(const float eloss, const float p_mass, const float p_charge) {
+	if (fk !=0 ) element_mat = rdipmat(element_length,fk,eloss,p_mass,p_charge);
+	else  {
+		element_mat = driftmat(element_length);
+		if(VERBOSE) cout<<"<H_RectangularDipole> WARNING : k0= 0, drift-like dipole (" << name << ") !" << endl;
+	}
+	return ;
+}
+
+H_RectangularDipole* H_RectangularDipole::clone() const {
+	H_RectangularDipole* temp_dip = new H_RectangularDipole(name,fs,fk,element_length);
+	temp_dip->setAperture(element_aperture);
+	temp_dip->setX(xpos);
+	temp_dip->setY(ypos);
+	temp_dip->setTX(txpos);
+	temp_dip->setTY(typos);
+	temp_dip->setBetaX(betax);
+	temp_dip->setBetaY(betay);
+	return temp_dip;
+}
+
Index: /trunk/Utilities/Hector/src/H_RomanPot.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_RomanPot.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_RomanPot.cc	(revision 3)
@@ -0,0 +1,68 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_RomanPot.cc
+/// \brief Roman pot class
+
+// local #includes
+#include "H_RomanPot.h"
+#include "H_RectangularAperture.h"
+#include "H_TransportMatrices.h"
+
+void H_RomanPot::init() {
+	// must be in public section
+		setTypeString();
+		setMatrix(0,MP,QP);
+	return;
+}
+
+H_RomanPot::H_RomanPot(const double s, const double app) :H_Drift(s,RP_LENGTH){
+		type = RP;
+		init();
+		H_RectangularAperture* rapp = new H_RectangularAperture(app,RP_HEIGHT,0,0);
+		setAperture(rapp);
+}
+
+H_RomanPot::H_RomanPot(const string nameE, const double s, const double app) :H_Drift(nameE,s,RP_LENGTH){
+		type = RP;
+		init();
+		H_RectangularAperture* rapp = new H_RectangularAperture(app,RP_HEIGHT,0,0);
+		setAperture(rapp);
+}
+
+void H_RomanPot::printProperties() const {
+		cout << typestring << name;
+		cout << "\t\t at s = " << fs;
+                if(element_aperture->getType()!=NONE) {
+                        cout <<"\t aperture type = " << element_aperture->getTypeString();
+                        element_aperture->printProperties();
+                }
+
+		cout<<endl;
+}
+
+void H_RomanPot::setMatrix(const float eloss, const float p_mass, const float p_charge) {
+		element_mat = driftmat(0);
+	return ;
+}
+
+H_RomanPot* H_RomanPot::clone() const {
+	H_RomanPot* temp_rp = new H_RomanPot(name,fs,element_length);
+	temp_rp->setAperture(element_aperture);
+	temp_rp->setX(xpos);
+	temp_rp->setY(ypos);
+	temp_rp->setTX(txpos);
+	temp_rp->setTY(typos);
+	temp_rp->setBetaX(betax);
+	temp_rp->setBetaY(betay);
+	return temp_rp;
+}
+
Index: /trunk/Utilities/Hector/src/H_SectorDipole.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_SectorDipole.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_SectorDipole.cc	(revision 3)
@@ -0,0 +1,38 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_SectorDipole.cc
+/// \brief Classes aiming at simulating sector dipoles
+
+#include "H_SectorDipole.h"
+#include "H_TransportMatrices.h"
+
+void H_SectorDipole::setMatrix(const float eloss, const float p_mass, const float p_charge) {
+	if (fk !=0 ) element_mat = sdipmat(element_length,fk,eloss,p_mass,p_charge);
+	else  {
+		element_mat = driftmat(element_length);
+		if(VERBOSE) cout<<"<H_SectorDipole> WARNING : k0= 0, drift-like dipole (" << name << ") !" << endl;
+   		}
+	return ;
+}
+
+H_SectorDipole* H_SectorDipole::clone() const {
+	H_SectorDipole* temp_dip = new H_SectorDipole(name,fs,fk,element_length);
+	temp_dip->setAperture(element_aperture);
+	temp_dip->setX(xpos);
+	temp_dip->setY(ypos);
+	temp_dip->setTX(txpos);
+	temp_dip->setTY(typos);
+	temp_dip->setBetaX(betax);
+	temp_dip->setBetaY(betay);
+	return temp_dip;
+}
+
Index: /trunk/Utilities/Hector/src/H_TransportMatrices.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_TransportMatrices.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_TransportMatrices.cc	(revision 3)
@@ -0,0 +1,295 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_TransportMatrices.cc
+/// \brief Includes the implementation of every transport matrix.
+
+// c++ #includes
+#include <iostream>
+
+// C #includes
+#include <cmath>
+
+// local #includes
+#include "H_Parameters.h"
+#include "H_TransportMatrices.h"
+using namespace std;
+
+bool relative_energy = 1;
+
+// caution : do not change particle mass, not implemented yet.
+
+extern double omega(const double k, const double l) {
+		// [l] = [m] and [k] = [1/mï¿œ] for quadrupoles
+		// [omega] = [1]
+	return sqrt(fabs(k))*l;
+}
+
+extern double radius(const double k) {
+		// [k] = [1/mï¿œ] for quadrupoles
+		// [k] = [1/m]  for dipoles
+		// [radius(k)] = [m]
+	if(k==0 && VERBOSE) cout<<"<H_TransportMatrices> ERROR : Dipole has no effect : results will be corrupted"<<endl; 
+	// this is protected by the "if(k==0) -> driftmat" in every matrix below (ex vquatmat)
+	return (k==0) ? 1 : 1/k;
+}
+
+extern void printMatrix(TMatrix TMat) {
+	char temp[20];
+	float * el = new float[MDIM*MDIM];
+	el = (TMat.GetMatrixArray());
+
+	cout << endl << "\t";
+	for(int i=0;i<MDIM*MDIM;i++) {
+		if (el[i]<0)
+  			 {sprintf(temp,"%.5e",el[i]);}
+		else if (el[i]>0)
+   			 {sprintf(temp," %.5e",el[i]);}
+   		else {sprintf(temp,"       0    ");}
+   		
+		cout << temp << " ";
+		if((i+1)%MDIM == 0) { cout << endl << "\t"; }
+	}
+	cout << endl;
+}
+
+extern TMatrix vquadmat(const float l, const float k, const float eloss = 0., const float p_mass=MP, const float p_charge=QP) {
+		// the length l is in [m]
+		// the strength k is in [1/mï¿œ] for quadrupoles
+		// eloss in [GeV]
+		// ke is the modified field with respect to the eloss
+                //  k = e/p * dB/dx with p = mv (and m = MP)
+                //  k -> ke = k * p/ (p - dp) <- chromacity
+                //  ke -> ke * p_charge / QP <- if not a proton
+                //  ke = 0 if charge = 0, whatever the mass
+                
+	const double p0 = sqrt( (BE-MP)*(BE+MP) );
+	const double E  = BE - eloss;
+	const double p  = sqrt( (E-p_mass)*(E+p_mass) );
+	const float ke = (p_charge==0) ? 0 : k* p0/p  *p_charge/QP;
+	if (ke==0) {
+		TMatrix drift(driftmat(l));		
+		return drift;
+	}
+	// else... : 
+	float om = omega(ke,l);
+	float * mat = new float[MDIM*MDIM];
+	float tmat[MDIM*MDIM] =  {cosh(om),sqrt(ke)*sinh(om),0.,0., 0.,0.,
+                           (1/sqrt(ke))*sinh(om),cosh(om),0.,0., 0.,0.,
+                           0.,0.,cos(om),-sqrt(ke)*sin(om), 0.,0.,
+                           0.,0.,(1/sqrt(ke))*sin(om),cos(om), 0.,0.,
+                           0., 0., 0., 0., 1., 0.,
+			   0., 0., 0., 0., 0., 1.
+	};
+	for (int i=0; i<MDIM*MDIM; i++) {mat[i] = tmat[i];}
+	TMatrix TMat(MDIM,MDIM,mat);
+	delete [] mat;
+    return TMat;
+}
+
+extern TMatrix hquadmat(const float l, const float k, const float eloss = 0., const float p_mass=MP, const float p_charge=QP) {
+		// the length l is in [m]
+		// the strength k is in [1/mï¿œ] for quadrupoles
+		// ke is the modified field with respect to the eloss
+                //  k = e/p * dB/dx with p = mv (and m = MP)
+                //  k -> ke = k * p/ (p- dp) <- chromacity
+                //  ke -> ke *p_charge/QP <- if not a proton
+        const double p0 = sqrt( (BE-MP)*(BE+MP) );
+        const double E  = BE - eloss;
+        const double p  = sqrt( (E-p_mass)*(E+p_mass) );
+        const float ke = (p_charge==0) ? 0 : fabs(k* p0/p)  *p_charge/QP;
+
+        if (ke==0) {
+		TMatrix drift(driftmat(l));
+		return drift;
+	}
+	float om = omega(ke,l);
+	float * mat = new float[MDIM*MDIM];
+	float tmat[MDIM*MDIM] =  {cos(om),-sqrt(ke)*sin(om),0.,0., 0., 0.,
+                           (1/sqrt(ke))*sin(om),cos(om),0.,0., 0., 0.,
+                           0.,0.,cosh(om),sqrt(ke)*sinh(om), 0., 0., 
+                           0.,0.,(1/sqrt(ke))*sinh(om),cosh(om), 0., 0.,
+                    	    0., 0., 0., 0., 1., 0.,
+                           0., 0., 0., 0., 0., 1. 
+	};
+	for(int i=0;i<MDIM*MDIM;i++) { mat[i] = tmat[i]; }
+	TMatrix TMat(MDIM,MDIM,mat);
+	delete [] mat;
+    return TMat;
+}
+
+extern TMatrix rdipmat(const float l, const float k, const float eloss = 0., const float p_mass=MP, const float p_charge=QP) {
+		// the length l is in [m]
+		// the strength k is in [1/m] for dipoles
+		// ke is the modified field with respect to the eloss
+                //  k = e/p * dB/dx with p = mv (and m = MP)
+                //  k -> ke = k * p/ (p- dp) <- chromacity
+                //  ke -> ke * q_mass/QP <- if not a proton
+
+        const double p0 = sqrt( (BE-MP)*(BE+MP) );
+        const double E  = BE - eloss;
+        const double p  = sqrt( (E-p_mass)*(E+p_mass) );
+        const float ke = (p_charge==0) ? 0 : k* p0/p  *p_charge/QP;
+ 
+        if (ke==0) {
+ 		TMatrix drift(driftmat(l));
+		return drift;
+	}
+	float r = radius(ke);
+	float * mat = new float[MDIM*MDIM];
+	float * efmat = new float[MDIM*MDIM];
+	double simp = r*2*sin(l/(2*r))*sin(l/(2*r))/BE;
+	double psy = ke*l/2.;
+	float tefmat[MDIM*MDIM] = {1., tan(psy)*ke, 0., 0., 0., 0.,
+	                            0., 1., 0., 0., 0., 0.,
+	                            0., 0., 1., -tan(psy)*ke, 0., 0.,
+	                            0., 0., 0., 1., 0., 0.,
+	                            0., 0., 0., 0., 1., 0.,
+	                            0., 0., 0., 0., 0., 1. };
+ 
+	float tmat[MDIM*MDIM] =  {cos(l/r),(-1/r)*sin(l/r),0.,0., 0., 0.,
+	             	           r*sin(l/r),cos(l/r),0.,0., 0., 0.,
+   		           	           0.,0.,1.,0., 0., 0.,
+   	            	           0.,0.,l,1., 0., 0., 
+   	                        simp, sin(l/r)/BE, 0., 0., 1., 0.,
+   	                        0., 0., 0., 0., 0., 1. };
+	for(int i=0;i<MDIM*MDIM;i++) { 
+		mat[i] = tmat[i];
+	    efmat[i] = tefmat[i];	
+	}
+	TMatrix TMat(MDIM,MDIM,mat);
+	TMatrix TEfmat(MDIM,MDIM,efmat);
+    if(relative_energy) {
+        TMat *= TEfmat;
+        TEfmat *= TMat;
+    }
+
+//	if(VERBOSE) cout<<"\t WARNING : RDipoles not implemented and replaced by SDipoles" << endl;
+	delete [] mat;
+	delete [] efmat;
+    if(relative_energy) {
+        return TEfmat;
+    } else {
+        return TMat;
+    }
+}
+
+extern TMatrix sdipmat(const float l, const float k, const float eloss = 0., const float p_mass=MP, const float p_charge=QP) {
+		// the length l is in [m]
+		// the strength k is in [1/m] for dipoles
+		// ke is the modified field with respect to the eloss
+                //  k = e/p * dB/dx with p = mv (and m = MP)
+                //  k -> ke = k * p/ (p- dp) <- chromacity
+                //  ke -> ke * q_mass/QP <- if not a proton
+                
+        const double p0 = sqrt( (BE-MP)*(BE+MP) );
+        const double E  = BE - eloss;
+        const double p  = sqrt( (E-p_mass)*(E+p_mass) );
+        const float ke = (p_charge==0) ? 0 : k* p0/p  *p_charge/QP;
+
+        if (ke==0) {
+		TMatrix drift(driftmat(l));
+		return drift;
+	}
+	extern bool relative_energy;
+	float r = radius(ke);
+  	float * mat = new float[MDIM*MDIM];
+
+	float simp = 2*r*sin(l/(2*r))*sin(l/(2*r))/BE;
+	float tmat[MDIM*MDIM] =  {cos(l/r),(-1/r)*sin(l/r),0.,0., 0., 0.,
+		                      r*sin(l/r),cos(l/r),0.,0., 0., 0.,
+			                  0.,0.,1.,0., 0., 0.,
+			                  0.,0.,l,1., 0., 0.,
+			                  simp, sin(l/r)/BE, 0., 0., 1., 0.,
+			                  0., 0., 0., 0., 0., 1.
+				           };
+	if(!relative_energy) {
+		tmat[24] = 0;
+		tmat[25] = 0;
+	} 
+
+	for(int i=0;i<MDIM*MDIM;i++) { mat[i] = tmat[i]; }
+	TMatrix TMat(MDIM,MDIM,mat);
+	delete [] mat;
+    return TMat;
+}
+
+extern TMatrix driftmat(const float l) {
+		// the length l is in [m]
+	float * mat = new float[MDIM*MDIM];
+	float tmat[MDIM*MDIM] =  {1.,0.,0.,0.,0.,0.,
+                           l ,1.,0.,0.,0.,0.,
+                           0.,0.,1.,0.,0.,0.,
+                           0.,0.,l ,1.,0.,0.,
+                           0.,0.,0.,0.,1.,0.,
+                           0., 0., 0., 0., 0., 1. 
+	};
+	for(int i=0;i<MDIM*MDIM;i++) { mat[i] = tmat[i]; }
+	TMatrix TMat(MDIM,MDIM,mat);
+	delete [] mat;
+	return TMat;
+}
+
+
+extern TMatrix hkickmat(const float l, const float k, const float eloss =0., const float p_mass=MP, const float p_charge=QP) {
+                // the length l is in [m]
+                // the strength k is in [rad]
+        const double p0 = sqrt( (BE-MP)*(BE+MP) );
+        const double E  = BE - eloss;
+        const double p  = sqrt( (E-p_mass)*(E+p_mass) );
+        const float ke = (p_charge==0) ? 0 : -k* p0/p  *p_charge/QP;
+
+        if (ke==0) {
+		TMatrix drift(driftmat(l));
+		return drift;
+	}
+	float * mat = new float[MDIM*MDIM];
+	float tmat[MDIM*MDIM] =  {1.,0.,0.,0.,0.,0.,
+                           l ,1.,0.,0.,0.,0.,
+                           0.,0.,1.,0.,0.,0.,
+                           0.,0.,l ,1.,0.,0.,
+                           0.,0.,0.,0.,1.,0.,
+                           l*tan(ke)/2.,ke, 0., 0., 0., 1. 
+	};
+
+	for(int i=0;i<MDIM*MDIM;i++) { mat[i] = tmat[i]; }
+	TMatrix TMat(MDIM,MDIM,mat);
+	delete [] mat;
+	return TMat;
+}
+
+extern TMatrix vkickmat(const float l, const float k, const float eloss=0., const float p_mass=MP, const float p_charge=QP) {
+                // the length l is in [m]
+                // the strength k is in [rad]
+        const double p0 = sqrt( (BE-MP)*(BE+MP) );
+        const double E  = BE - eloss;
+        const double p  = sqrt( (E-p_mass)*(E+p_mass) );
+        const float ke = (p_charge==0) ? 0 : -k* p0/p  *p_charge/QP;
+
+        if (ke==0) {
+		TMatrix drift(driftmat(l));
+		return drift;
+	}
+	float * mat = new float[MDIM*MDIM];
+	float tmat[MDIM*MDIM] =  {1.,0.,0.,0.,0.,0.,
+                           l ,1.,0.,0.,0.,0.,
+                           0.,0.,1.,0.,0.,0.,
+                           0.,0.,l ,1.,0.,0.,
+                           0.,0.,0.,0.,1.,0.,
+                           0.,0.,l*tan(ke)/2.,ke, 0., 1. 
+	};
+
+	for(int i=0;i<MDIM*MDIM;i++) { mat[i] = tmat[i]; }
+	TMatrix TMat(MDIM,MDIM,mat);
+	delete [] mat;
+	return TMat;
+}
+
Index: /trunk/Utilities/Hector/src/H_VerticalKicker.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_VerticalKicker.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_VerticalKicker.cc	(revision 3)
@@ -0,0 +1,43 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_VerticalKicker.cc
+/// \brief Classes aiming at simulating vertical kickers in the beamline
+
+// fk [rad] for kickers !!!!
+
+// local #includes
+#include "H_VerticalKicker.h"
+#include "H_TransportMatrices.h"
+
+void H_VerticalKicker::setMatrix(const float eloss, const float p_mass, const float p_charge) {
+	extern int kickers_on;
+	if(kickers_on) {
+		element_mat = vkickmat(element_length,fk,eloss,p_mass,p_charge);
+	} else{
+		element_mat = driftmat(element_length);
+	}
+	return ;
+}
+
+H_VerticalKicker* H_VerticalKicker::clone() const {
+	H_VerticalKicker* temp_kick = new H_VerticalKicker(name,fs,fk,element_length);
+	temp_kick->setAperture(element_aperture);
+	temp_kick->setX(xpos);
+	temp_kick->setY(ypos);
+	temp_kick->setTX(txpos);
+	temp_kick->setTY(typos);
+	temp_kick->setBetaX(betax);
+	temp_kick->setBetaY(betay);
+	return temp_kick;
+}
+
+
Index: /trunk/Utilities/Hector/src/H_VerticalQuadrupole.cc
===================================================================
--- /trunk/Utilities/Hector/src/H_VerticalQuadrupole.cc	(revision 3)
+++ /trunk/Utilities/Hector/src/H_VerticalQuadrupole.cc	(revision 3)
@@ -0,0 +1,38 @@
+/*
+---- Hector the simulator ----
+   A fast simulator of particles through generic beamlines.
+   J. de Favereau, X. Rouby ~~~ hector_devel@cp3.phys.ucl.ac.be
+
+        http://www.fynu.ucl.ac.be/hector.html
+
+   Centre de Physique des Particules et de PhÃ©nomÃ©nologie (CP3)
+   UniversitÃ© Catholique de Louvain (UCL)
+*/
+
+/// \file H_VerticalQuadrupole.cc
+/// \brief Vertically focussing quadrupoles
+
+// local #includes
+#include "H_VerticalQuadrupole.h"
+
+void H_VerticalQuadrupole::setMatrix(const float eloss, const float p_mass, const float p_charge) {
+	if (fk<0)  { if(VERBOSE) cout<<"<H_VerticalQuadrupole> ERROR : k1 should be > 0 for H_VerticalQuadrupole (" << name << ")!"<<endl; }
+		if (fk !=0 ) element_mat = vquadmat(element_length,fk,eloss, p_mass,p_charge);
+		else  {
+			element_mat = driftmat(element_length);
+			if(VERBOSE) cout<<"<H_VerticalQuadrupole> WARNING : k1= 0, drift-like quadrupole (" << name << ") !" << endl;
+   		}
+	return ;
+}
+
+H_VerticalQuadrupole* H_VerticalQuadrupole::clone() const {
+	H_VerticalQuadrupole* temp_quad = new H_VerticalQuadrupole(name,fs,fk,element_length);
+	temp_quad->setAperture(element_aperture);
+	temp_quad->setX(xpos);
+	temp_quad->setY(ypos);
+	temp_quad->setTX(txpos);
+	temp_quad->setTY(typos);
+	temp_quad->setBetaX(betax);
+	temp_quad->setBetaY(betay);
+	return temp_quad;
+}
Index: /trunk/Utilities/mcfio/CREDITS
===================================================================
--- /trunk/Utilities/mcfio/CREDITS	(revision 3)
+++ /trunk/Utilities/mcfio/CREDITS	(revision 3)
@@ -0,0 +1,1 @@
+not available
Index: /trunk/Utilities/mcfio/VERSION
===================================================================
--- /trunk/Utilities/mcfio/VERSION	(revision 3)
+++ /trunk/Utilities/mcfio/VERSION	(revision 3)
@@ -0,0 +1,1 @@
+not available
Index: /trunk/Utilities/mcfio/mcf_NTuIOFiles.c
===================================================================
--- /trunk/Utilities/mcfio/mcf_NTuIOFiles.c	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_NTuIOFiles.c	(revision 3)
@@ -0,0 +1,965 @@
+/*******************************************************************************
+*									       *
+* mcf_NTuIOFiles.c -- Utilities to manipulate files within the MCFIO Gen.      *
+*        				Ntuple schema                          *
+*									       *
+*	P. Lebrun, September 1995.					       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <limits.h>
+#include <time.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <rpc/xdr.h>
+#include <unistd.h>
+#include <ctype.h>
+#include "mcf_nTupleDescript.h"
+#include "mcf_xdr.h"
+#include "mcfio_Dict.h"
+#include "mcfio_Direct.h"
+#include "mcfio_Util1.h"
+#include "mcf_NTuIOFiles.h"
+#include "mcf_NTuIOUtils.h"
+#include "mcf_ntubld_db.h"
+#include "mcf_ntuBldDbinc.h"
+#ifndef False
+#define False 0
+#endif
+#ifndef True
+#define True 1
+#endif
+
+extern char *VarTypesNamesF77[N_VAR_TYPES];
+extern char *VarTypesNamesC[N_VAR_TYPES];
+
+extern struct line_title_c line_title_c_;
+extern struct header_c header_c_;
+extern struct variable_c variable_c_;
+
+/*
+** Ntuple identifiers list, initialized here and in mcfio_Util1
+*/
+nTuDDL **NTuDDLList = NULL;
+int NumOfNTuples = 0;
+bool_t McfNTuPleSaveDecoding = True;
+
+static char *makeStructName(char *title, int orgStyle);
+static size_t nDatVariable(varGenNtuple *varTmp);
+static size_t sizeVariable(varGenNtuple *varTmp);
+static char *mcf_copyNtrim(char *fromString);
+
+int mcfioC_DeclareNtuple(int uid, char *title, char *category, 
+                                int stream, char *filename)
+{
+    nTuDDL *ddl, *ddlRef;
+    int i, j, jstr, dejaVu, id, **ip;
+    
+    
+    if ((stream < 1) || (stream > MCF_STREAM_NUM_MAX)) {
+     fprintf(stderr,
+  " mcfio_NtupleDDLRead: Illegal MCFIO stream number.\n"); 
+     return -1;
+    }
+    jstr = stream-1;
+    if (McfStreamPtrList[jstr] == NULL) { 
+        fprintf(stderr,
+   " mcfio_DeclareNtuple: First, declare the stream by calling mcfio_Open...\n"); 
+     return -1;
+    }
+      
+    if (McfStreamPtrList[jstr]->row != MCFIO_WRITE) {
+        fprintf(stderr,
+   " mcfio_DeclareNtuple: You must declare an Ntuple for an Output Stream\n"); 
+     return -1;
+    }
+        
+    if (!mcf_CheckValidCat(category, False)) return 0;
+    
+    /* Check that this item characterized by uid/Category has not already been 
+         created. If so, do not create a new one.  If associated to the same
+         stream, flag this as an error. */
+    
+    id = mcf_NTuId(uid, category);			
+    if (id != -1) {
+       ddl = mcf_GetNTuByPtrID(id);
+       if (ddl->streamId == stream) {  
+        fprintf(stderr,
+        "Mcfio Declare Ntuple:  An item with this uid/Category already exists.\n");
+        fprintf(stderr, "  uid = %d, Category = %s, ", uid, category);
+        fprintf(stderr, "Ntuple not created.\n");
+        return -1;
+        }
+     }
+     /*
+     ** May be this dbin template has already been digested. If so, refer
+     ** to it, to avoid re-computing all the offsets.
+    */
+     ip = (int **) NTuDDLList;
+     for (i=0, dejaVu=False; i< NumOfNTuples; i++, ip++) {
+	 ddlRef = (nTuDDL *) *ip;
+         if ((ddlRef->dbinFileName != NULL) && 
+             (strcmp(filename, ddlRef->dbinFileName) == 0)) {
+             dejaVu = True;
+            /* Create a holder for this Ntuple Description */
+             ddl = (nTuDDL * ) malloc(sizeof(nTuDDL));
+             /*
+             ** back up in the linked list if need be, until we 
+             ** a fully documented descriptor.
+             */
+             while (ddlRef->descrNtu == NULL) ddlRef = ddlRef->reference;
+             ddl->reference = ddlRef; 
+             ddl->descrNtu = NULL;
+             ddl->dbinFileName = NULL;
+             break;
+         }
+     }
+     if (dejaVu == False)  {
+         ddl = mcf_GetFileNTuDDL(filename);
+         if (ddl == NULL) { 
+              fprintf(stderr,
+                  " mcfio_NtupleDDLRead: Error reading %s\n", filename );
+                 return -1; 
+         }
+         ddl->reference = NULL;
+    }
+    ddl->title = mcf_copyNtrim(mcf_ValidStr(title, NTU_MAX_TITLE_LENGTH, 
+    				 "title"));
+    if (category == NULL)
+      ddl->category = 
+         mcf_copyNtrim(mcf_ValidStr(category, NTU_MAX_CATEGORY_LENGTH, 
+    				 "category"));
+    else {
+	ddl->category = mcf_copyNtrim(category);
+    }
+    AddNTuDDLtoList(ddl);
+/*
+** Now we compute the offssets. 
+*/
+    if (dejaVu == False)  {
+        mcf_ComputeNTuOffsets(ddl);    
+/*
+** Now we compute the lengths..
+*/
+       mcf_ComputeNTuLengths(ddl);
+    }
+    ddl->uid = uid;
+    ddl->streamId = stream;
+    /*
+    ** Set the sequential id for this particular stream
+    */
+    for (i=0, j=0; i<NumOfNTuples; i++) 
+        if (NTuDDLList[i]->streamId == ddl->streamId) j++;
+    ddl->seqNTuId = j;
+    (McfStreamPtrList[jstr]->fhead->nNTuples)++;
+    return ddl->seqNTuId;
+}
+     
+int mcfioC_EndDeclNTuples(int stream)
+/*
+** Routine to end theNtuple delcaration and rewrite the beginning of the 
+** file.
+*/
+{
+   int i, jstr;
+   u_int p1;
+   FILE *ff;
+   mcfStream *str;
+   
+  if (McfStreamPtrList == NULL) { 
+     fprintf(stderr,
+  " mcfio_EndDeclNtuple: No stream open, No inialization.\n"); 
+     return -1;
+  }
+  jstr = stream-1;
+  if (McfStreamPtrList[jstr] == NULL) { 
+     fprintf(stderr,
+ " mcfio_EndDeclNtuple: First, declare the stream by calling mcfio_Open...\n"); 
+     return -1;
+  }
+  str = McfStreamPtrList[jstr];
+  if (str->row != MCFIO_WRITE) {
+     fprintf(stderr,
+ " mcfio_EndDeclNtuple: This routine is not applicable to Input streams...\n"); 
+     return -1;
+  }
+  if (str->fhead->nNTuples < 1) {
+     fprintf(stderr,
+ " mcfio_EndDeclNtuple: No Ntuple declared for this stream...\n"); 
+     return 0;
+  }     
+   /*
+   ** Now we can try toto complete the file header. As it is now bigger, 
+   ** and it is the first structure written, it is easier to start over.
+   ** Destroy the XDR stream, close the file, and reopen it.
+   */  
+   xdr_destroy(str->xdr);
+   fclose(str->filePtr);
+   remove(str->filename);
+   ff = fopen(str->filename, "w");
+   if (ff == NULL) {
+     fprintf(stderr,
+  " mcfio_EndDeclNtuple: Problem re-opening file %s, message \n", 
+        str->filename);
+     return -1;
+   }
+   xdrstdio_create(str->xdr, ff, XDR_ENCODE);
+   p1 = xdr_getpos(str->xdr);
+   str->firstPos = p1;
+   str->currentPos = p1;
+   /*
+   ** In the file header, we do not store the NTuple Ids, as they are 
+   ** not necessarily valid in an other context, where we have different
+   ** streams/NTuples combinations. The SeqNTuId are trivial, 
+   ** within a stream, at the file header (1,2,3,..) 
+   **  But, of course, we must provide an array for the event header..
+   */
+   str->ehead->dimNTuples = str->fhead->nNTuples;
+   str->ehead->nNTuples = 0;
+   str->ehead->nTupleIds = 
+          (int *) malloc(sizeof(int) * str->fhead->nNTuples);
+   
+   str->ehead->ptrNTuples = 
+          (u_int *) malloc(sizeof(u_int) * str->fhead->nNTuples);
+   for (i=0; i<str->ehead->dimNTuples; i++) str->ehead->ptrNTuples[i]=0;       
+   
+   str->status = MCFIO_BOF;
+   if (mcfioC_Wrtfhead(str, INITIATE) == FALSE){
+       mcfioC_FreeStream(&McfStreamPtrList[jstr]);
+       fclose(ff);
+       return -1;
+   }
+   /*
+   ** Write the first dummy table 
+   */
+   if (mcfioC_Wrttable(str, INITIATE) == FALSE) return -1;
+   /*
+   ** Write the first dummy event header
+   */
+   if (mcfioC_WrtEvt(str, INITIATE) == FALSE) return -1;
+   str->ehead->evtnum = 0;
+   str->status = MCFIO_RUNNING;
+   return (str->fhead->nNTuples);
+}
+
+nTuDDL *mcf_GetFileNTuDDL(char*filename)
+{
+    nTuDDL *ddl;
+    int i, l, j;
+    char *text, *tc;
+    varGenNtuple *varTmp;
+    descrGenNtuple *dNTu;
+    
+    /* Create a holder for this Ntuple Description */
+    ddl = (nTuDDL * ) malloc(sizeof(nTuDDL));
+    ddl->dbinFileName = (char *) malloc(sizeof(char) * (strlen(filename) +1));
+    strcpy(ddl->dbinFileName, filename);
+    ddl->descrNtu = (descrGenNtuple *) malloc(sizeof(descrGenNtuple));
+    dNTu = ddl->descrNtu;
+    
+    header_c_.n_obj_header = 0;
+    line_title_c_.n_obj_line_title = 0;
+    mcf_ntubldRead(filename);
+    if ((line_title_c_.n_obj_line_title < 1)  ||
+        (header_c_.n_obj_header != 1)) {
+        fprintf(stderr, 
+                " This file was not created by the ntuBuild aplication!");
+        return NULL;
+    }
+    if (strcmp(line_title_c_.line_title[0].line,
+               "ntuBuild Database, v1.0") != 0) {
+        fprintf(stderr, 
+                " This file was not created by a wrong version of ntuBuild!");
+        return NULL;
+    }
+    /*
+    ** There are 80 character per lines in dbin..
+    */
+    text = (char *)
+            malloc(sizeof(char) * 80 * (line_title_c_.n_obj_line_title -1));
+    for (i=1, tc=text; i<line_title_c_.n_obj_line_title; i++) {
+        strcpy(tc, line_title_c_.line_title[i].line); 
+        tc += strlen(line_title_c_.line_title[i].line);
+        *tc = '\n'; tc++;
+    }
+    *tc = '\0';
+    dNTu->description = text;
+    
+    l = strlen(header_c_.header[0].title);
+    dNTu->title = (char *) malloc(sizeof(char) * (l+1));
+    strcpy(dNTu->title, header_c_.header[0].title);
+    
+    strcpy(dNTu->version, header_c_.header[0].version);
+    
+    strcpy(dNTu->nameIndex, header_c_.header[0].namemaxindex);
+    
+    dNTu->maxMultiplicity = header_c_.header[0].maxmult;
+    
+    dNTu->orgStyle = header_c_.header[0].orgstyle;
+    dNTu->numVariables = header_c_.header[0].nvar;
+    dNTu->numAvailable = dNTu->numVariables;
+    dNTu->variables =
+     (varGenNtuple **) malloc(sizeof(varGenNtuple *) * dNTu->numVariables);
+    /*
+    ** Now the variables
+    */
+    for (i=0; i<variable_c_.n_obj_variable; i++) {
+        dNTu->variables[i] =   
+                (varGenNtuple *) malloc(sizeof(varGenNtuple));
+        varTmp = dNTu->variables[i];
+        varTmp->nameBlank = False;
+        varTmp->name = (char *)
+            malloc(sizeof(char) * (strlen(variable_c_.variable[i].name) + 1));
+        strcpy(varTmp->name, variable_c_.variable[i].name);
+        
+        if ((strlen(variable_c_.variable[i].description) > 1) ||
+                    variable_c_.variable[i].description[0] != ' ') { 
+           varTmp->description = (char *) malloc(sizeof(char) * 
+                (strlen(variable_c_.variable[i].description) + 1));
+           strcpy(varTmp->description, variable_c_.variable[i].description);
+        } else varTmp->description = NULL;  
+        varTmp->type = variable_c_.variable[i].type;
+        varTmp->isFixedSize = True;
+        if (strncmp(variable_c_.variable[i].isfixedsize,"Yes",3))
+            varTmp->isFixedSize = False;
+        varTmp->numDim = variable_c_.variable[i].numdim;
+        if (varTmp->numDim > 0) 
+           for (j=0; j< varTmp->numDim; j++)
+               varTmp->dimensions[j] = variable_c_.variable[i].dimensions[j];
+                
+    }
+    /*
+    ** Set the ordering. Trivial in this case, it has been ordered in 
+    ** the save routine.
+    */
+    dNTu->varOrdering = (int *) malloc(sizeof(int) * dNTu->numAvailable);
+    for (i=0; i<dNTu->numVariables; i++)
+       dNTu->varOrdering[i] = i; 
+    dNTu->subOffset = NULL;
+    dNTu->subXDROffset = NULL;    
+    return ddl;
+    
+}
+
+/*
+** Compute the offsets by writing a simple program, stand alone, that uses
+** the d/s
+*/
+void    mcf_ComputeNTuOffsets(nTuDDL *ddl)    
+{
+     char tmpName[128], *tc, *tc1, *nameCom;
+     int i, j, l, fd, firstIndexed, nDat;
+     char filenameInclude[128], filenameProgram[128], filenameExec[128];
+     char filenameData[128], nameMaxIndex[32];
+     char line[256];
+     void **ptrBegVar;
+     varGenNtuple *varTmp;
+     descrGenNtuple *dNTu;
+     FILE *Ffp;
+     
+     dNTu =ddl->descrNtu;  
+     for (i=0; i< dNTu->numVariables; i++) { 
+        varTmp = dNTu->variables[i];
+        varTmp->offset = 0;
+     }
+        
+     memset(tmpName, 0, 127);
+     tc = tmpName;
+     sprintf(tc, "tmp_%s_XXXXXX", ddl->descrNtu->title);
+/* this is a kludge - we create a temporary file, close it, and use the name */
+     fd = mkstemp(tmpName);
+     if ( fd < 0 ) {
+         fprintf(stderr, 
+        " Can not compose a tempoary name in mcf_ComputeOffsets!");
+         return;
+     }
+     tc1 = tc;
+     close(fd);
+     sprintf(filenameInclude, "%s.h", tc1);
+     sprintf(filenameProgram, "%s.c", tc1);
+     sprintf(filenameData, "%s.dat", tc1);
+     strcpy(filenameExec, tc1);
+     mcf_ComposeDoth(ddl->descrNtu, filenameInclude);
+/*
+** Compose a little moronic program that establishes the addresses of all 
+** variables. There might be a better way, though.. However, this ought to be
+** safe. 
+*/
+     Ffp =  fopen( filenameProgram, "w");
+     fprintf(Ffp, "#include <stdio.h>\n");
+     fprintf(Ffp, "#include \"%s\"\n",filenameInclude);
+     if (dNTu->orgStyle == PARALLEL_ARRAY_NTU)
+         fprintf(Ffp, "#define NUM_VAR %d\n", (dNTu->numVariables+3));
+     else 
+         fprintf(Ffp, "#define NUM_VAR %d\n",
+                (dNTu->numVariables + 3 + dNTu->maxMultiplicity) );
+         
+     nameCom = makeStructName(dNTu->title, dNTu->orgStyle);
+     
+     fprintf(Ffp, "%s_struct tmpStruct; \n", nameCom);
+     fprintf(Ffp, "main(int argc, char **argv)\n");
+     fprintf(Ffp, "{\n");
+     fprintf(Ffp, "    void *ptrBegVar[NUM_VAR];\n");
+     fprintf(Ffp, "    FILE *Ffp;\n");
+     fprintf(Ffp, "    int i;\n");
+     fprintf(Ffp, "\n");
+     fprintf(Ffp, "    ptrBegVar[0] = (void *) &tmpStruct.version[0];\n");
+     fprintf(Ffp,
+      "    ptrBegVar[1] = (void *) &tmpStruct.%s;\n",dNTu->nameIndex);
+     for(i=0, firstIndexed=-1; i<dNTu->numVariables; i++) {
+           if (dNTu->variables[i]->isFixedSize == False) {
+                  firstIndexed = i; break;
+           }       
+     }
+     dNTu->firstIndexed = firstIndexed;             
+     if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
+         for(i=0; i<dNTu->numVariables; i++) {
+           varTmp =  dNTu->variables[i];
+           /*
+           ** Assume that all the variables are properly 
+           ** defined at this stage (e..g, coming from a valid DDL dbin file)
+           ** and in order
+           */
+           tc = line;
+           if ((varTmp->numDim == 0) && (varTmp->isFixedSize == True)) 
+               sprintf(tc,
+                "    ptrBegVar[%d] = (void *) &tmpStruct.%s%n",
+                    (i+2), varTmp->name, &l);
+           else           
+               sprintf(tc,
+                "    ptrBegVar[%d] = (void *) tmpStruct.%s%n",
+                    (i+2), varTmp->name, &l);
+           tc+=l;
+           fprintf(Ffp, "%s;\n", line);    
+         }
+         fprintf(Ffp,
+      "    ptrBegVar[%d] = (void *) tmpStruct.fence;\n",dNTu->numVariables+2);
+     } else {
+         for(i=0; i<dNTu->numVariables; i++) {
+           varTmp =  dNTu->variables[i];
+           tc = line;
+           if (varTmp->isFixedSize == True) {
+              if (varTmp->numDim == 0)
+                sprintf(tc,
+               "    ptrBegVar[%d] = (void *) &tmpStruct.%s%n",
+                    (i+2), varTmp->name, &l);
+               else 
+                sprintf(tc,
+               "    ptrBegVar[%d] = (void *) tmpStruct.%s%n",
+                    (i+2), varTmp->name, &l);
+           } else {
+               if (varTmp->numDim == 0)         
+                   sprintf(tc,
+                   "    ptrBegVar[%d] = (void *) &tmpStruct.var[0].%s%n",
+                    (i+2), varTmp->name, &l);
+               else 
+                   sprintf(tc,
+                   "    ptrBegVar[%d] = (void *) tmpStruct.var[0].%s%n",
+                    (i+2), varTmp->name, &l);
+           }                                     
+           fprintf(Ffp, "%s;\n", line); 
+         }
+         tc1 = dNTu->nameIndex;
+         strcpy(nameMaxIndex, tc1);
+         l = strlen(tc1); 
+         if (l > 26) {
+            strncpy(nameMaxIndex, tc1, 26);
+            sprintf(&nameMaxIndex[26],"_max");
+         } else
+            sprintf(nameMaxIndex, "%s_max", tc1);
+         fprintf(Ffp,"    for (i=0; i<%s; i++) \n", nameMaxIndex);
+         tc = line;
+         if (firstIndexed != -1) {
+             varTmp = dNTu->variables[firstIndexed];
+             sprintf(tc,
+             "       ptrBegVar[i+%d] = (void *) &tmpStruct.var[i].%s%n",
+              (2+dNTu->numVariables), varTmp->name, &l); tc+=l;
+              if (varTmp->numDim > 0) for (j=0; j<varTmp->numDim; j++, tc+=l) 
+                                             sprintf(tc, "[0]%n", &l);   
+              fprintf(Ffp, "%s;\n", line);
+         }      
+         fprintf(Ffp,
+      "    ptrBegVar[%d] = (void *) tmpStruct.fence;\n",
+              dNTu->numVariables+2+dNTu->maxMultiplicity);
+     }
+     fprintf(Ffp, " ");
+     fprintf(Ffp,"    Ffp = fopen(\"%s\",\"w\");\n",filenameData);
+     fprintf(Ffp,"    fwrite((void *) ptrBegVar, sizeof(void *),\
+(size_t) NUM_VAR, Ffp);\n");
+     fprintf(Ffp,"    fclose(Ffp);\n");
+     fprintf(Ffp,"}\n");
+     fclose(Ffp);
+     free(nameCom);
+     /*
+     ** Now compile, link and load this exec, read the result
+     */
+     sprintf(line,"rm -f %s", filenameExec);
+     system(line);
+#ifdef _HPUX_SOURCE
+     sprintf(line,"cc -Aa -D_HPUX_SOURCE -o %s %s", 
+                            filenameExec, filenameProgram);
+#else
+     sprintf(line,"cc -o %s %s", filenameExec, filenameProgram);
+#endif
+     system(line);
+     sprintf(line,"./%s", filenameExec);
+     system(line);
+     if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) nDat = dNTu->numVariables+3;
+        else nDat = dNTu->numVariables+3+dNTu->maxMultiplicity;
+     if (firstIndexed == -1) nDat = dNTu->numVariables+3;   
+     ptrBegVar = (void **) malloc (sizeof(void *) * (nDat));
+     Ffp = fopen(filenameData, "r");
+     fread((void *) ptrBegVar, sizeof(void *), (size_t) nDat, Ffp);
+     fclose(Ffp);
+     /*
+     ** remove garbage files..
+     */
+     remove(filenameData); remove(filenameProgram); remove(filenameExec);
+     remove(filenameInclude);
+     /*
+     ** Convert these addresses to offsets
+     */
+     dNTu->multOffset =  ((long) ptrBegVar[1] - (long) ptrBegVar[0]);
+     if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
+         dNTu->fenceOffset =
+          ((long) ptrBegVar[dNTu->numVariables+2] - (long) ptrBegVar[0]); 
+         for (i=0; i< dNTu->numVariables; i++) 
+            dNTu->variables[i]->offset = 
+                   ((long) ptrBegVar[i+2] - (long) ptrBegVar[0]);
+     } else {
+         for (i=0; i< dNTu->numVariables; i++) {
+            varTmp = dNTu->variables[i]; 
+            if (varTmp->isFixedSize)
+                varTmp->offset = 
+                    ((long) ptrBegVar[i+2] - (long) ptrBegVar[0]);
+            else 
+                varTmp->offset = 
+                   ((long) ptrBegVar[i+2] - (long)ptrBegVar[firstIndexed+2]);
+         }
+         if (dNTu->subOffset != NULL) free(dNTu->subOffset);
+         dNTu->subOffset =
+            (long *) malloc(sizeof(long) * dNTu->maxMultiplicity);
+         if (firstIndexed != -1) {    
+            for (i=0; i<dNTu->maxMultiplicity; i++) 
+                dNTu->subOffset[i] =          
+               ((long) ptrBegVar[i+2+dNTu->numVariables]  - 
+               (long) ptrBegVar[0]);
+         }          
+         dNTu->fenceOffset =
+            ((long) ptrBegVar[dNTu->numVariables+2+dNTu->maxMultiplicity]
+                     - (long) ptrBegVar[0]); 
+     }   
+     free(ptrBegVar);
+}
+
+/*
+** Compute the lengths for the XDR Array statements. It is assumed that the 
+** NTUple descriptor is sorted, no blank variables.
+*/
+void    mcf_ComputeNTuLengths(nTuDDL *ddl)    
+{
+     int i, j, lastTmp, sameType;
+     size_t nDat, sizeItem;
+     varGenNtuple *var1, *var2;
+     descrGenNtuple *dNTu;
+     
+     dNTu =ddl->descrNtu;
+     if (dNTu->firstIndexed != -1) lastTmp = dNTu->firstIndexed;
+         else lastTmp = dNTu->numVariables;
+     /*
+     ** fixed size first.. 
+     */   
+     for (i=0; i<lastTmp; i++)
+         dNTu->variables[i]->lengthW = nDatVariable(dNTu->variables[i]); 
+/*
+** This, in principle, is the optimized version, where we collaps single
+** fields of the same type into an array. However, this is machine 
+** dependant.
+*/                                    
+     for (i=0; i<lastTmp; i++) {
+         var1 = dNTu->variables[i];
+         if (var1->lengthW != 0) {
+            nDat = nDatVariable(var1);
+            j=i+1;
+            sizeItem = sizeVariable(var1); 
+            sameType = True;
+            while ((j<lastTmp) && (sameType)) { 
+               var2 = dNTu->variables[j];
+               if (var2->type != var1->type) sameType = False;
+               if (sameType  && ((( var2->offset - 
+                                    var1->offset)/sizeItem) ==
+                                     nDat)) {
+                  nDat += nDatVariable(var2);
+                  var2->lengthW = 0; j++;
+               }
+            }
+            var1->lengthW = nDat;
+            var1->lengthB = nDat*sizeItem;
+         }
+     } 
+     /*
+     ** The variable size, similar code. This fill is very simple if the 
+     ** if the organisation is parallel arrays, as we can not implmenent
+     ** compaction 
+     */           
+     if (dNTu->firstIndexed == -1) return;
+     if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
+         for (i=dNTu->firstIndexed; i<dNTu->numVariables; i++) { 
+              dNTu->variables[i]->lengthW
+                          =  nDatVariable(dNTu->variables[i]);
+              dNTu->variables[i]->lengthB = dNTu->variables[i]->lengthW   
+                         * sizeVariable(dNTu->variables[i]);
+         }                
+     } else {
+         for (i=dNTu->firstIndexed; i<dNTu->numVariables; i++) 
+            dNTu->variables[i]->lengthW =  nDatVariable(dNTu->variables[i]);
+         for (i=dNTu->firstIndexed; i<dNTu->numVariables; i++) {
+             var1 = dNTu->variables[i];
+             if (var1->lengthW != 0) {
+                 nDat = nDatVariable(var1);
+                 j=i+1;
+                 sizeItem = sizeVariable(var1); 
+                 sameType = True;
+                 while ((j<dNTu->numVariables) && (sameType)) { 
+                    var2 = dNTu->variables[j];
+                    if (var2->type != var1->type) sameType = False;
+                    if (sameType  && (((var2->offset - 
+                                   var1->offset)/sizeItem) ==
+                                     nDat)) {
+                     nDat += nDatVariable(var2);
+                     var2->lengthW = 0; j++; 
+                  }
+                }
+                var1->lengthW = nDat;
+                var1->lengthB = nDat*sizeItem;
+             }
+         }
+     }
+     
+}
+/*
+** Compute, in size_t units (bytes, I hope) the length of a particular
+** variable.  Only the fixed size part, we will have to multiplity 
+** by the multiplicty in the XDR filter.
+*/
+
+static size_t nDatVariable(varGenNtuple *var)
+{
+   size_t n;
+   int i;
+    
+    n=1;
+    for (i=0; i<var->numDim; i++) n = n * var->dimensions[i];
+    return n;
+}
+static size_t sizeVariable(varGenNtuple *var)
+{
+   size_t n;
+   
+   switch (var->type) {
+        case BYTE_NTU: case CHARACTER_NTU:
+           n = sizeof(char);
+           break;
+        case INTEGER2_NTU:
+           n = sizeof(short);
+           break;
+        case LOGICAL_NTU: case INTEGER_NTU:
+           n = sizeof(int);
+           break;
+        case REAL_NTU:
+           n = sizeof(float);
+           break;
+        case DBL_PRECISION_NTU:
+           n = sizeof(double);
+           break;
+        case COMPLEX_NTU:
+           n = 2 * sizeof(float);
+           break;
+        case DBL_COMPLEX_NTU:
+           n = 2 * sizeof(double);
+           break;
+        case POINTER_NTU:
+           n = sizeof(void *);
+           break;
+        default : 
+           fprintf(stderr, " mcf_ComputNTuLength, internal error \n");
+           n = 0;
+           break;
+    }
+    return n;
+}
+
+/*
+** Compose the .h file. Called from NTuBldMenu and this file. The structure 
+** is assumed valid. 
+*/
+void    mcf_ComposeDoth(descrGenNtuple *dNTu, char *filename)
+{
+    char *nameCom, line[FILENAME_MAX+500], *tmp, *version, *text, *tc, *tc2;
+    char nameMaxIndex[32], nameTmpIndex[32];
+    char nullDescr[4], *descrTmp;
+    int i, j, l, kmode, nc, ncTot, nl, iv;
+    time_t clock;
+    FILE *Ffp;
+    varGenNtuple *var;
+    
+    nameCom = makeStructName(dNTu->title, dNTu->orgStyle);
+    strcpy(nullDescr, "? ");
+    strcpy(line, filename);
+    tc = strchr(line, '.');
+    if (tc == NULL) {
+         l = strlen(filename);
+         tc = line; tc+=l;
+    }     
+    strcpy(tc,".h");   
+    Ffp = fopen(line, "w");
+    fprintf(Ffp,"/* ntuBuild\n");
+    time(&clock);
+    tmp = line; sprintf(tmp,"** Creation Date : %n", &l); tmp += l;
+    strncpy(tmp,ctime(&clock), 24); tmp += 24; *tmp='\n'; tmp++; *tmp = '\0';
+    fprintf(Ffp,line);
+    fprintf(Ffp,"**  User Comments\n");
+    text = dNTu->description;
+    tc = text; 
+    if (*tc == '\0') 
+       fprintf(Ffp,"** no user comments\n");
+    else {
+       ncTot = strlen(tc); nc =0;
+       while (nc < ncTot) {
+            tc2 = strchr(tc,'\n');
+            nl = (int) (tc2-tc)/sizeof(char);
+            if ((tc2 == NULL) || (nl > 75)) nl = 75;
+            strncpy(line, tc, nl); line[nl] = '\0';
+            fprintf (Ffp,"** %s\n", line);
+            tc += nl; nc += nl;
+            if (*tc == '\n') {
+               tc++;
+               nc++;
+            }
+       }
+    }
+    fprintf(Ffp,"*/    \n");
+    version = dNTu->version;
+    text = dNTu->nameIndex;
+    strcpy(nameTmpIndex, text);
+    l = strlen(text); 
+    if (l > 26) {
+            strncpy(nameMaxIndex, text, 26);
+            sprintf(&nameMaxIndex[26],"_max");
+    } else
+            sprintf(nameMaxIndex, "%s_max", text);
+    fprintf(Ffp,"#define %s %d\n", nameMaxIndex, dNTu->maxMultiplicity);        
+    if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
+        fprintf(Ffp, "typedef struct _%s_struct {\n", nameCom);
+        /*
+        ** The first 64 bits contain the version token, as a char[8] string
+        ** floowed by the multiplicty variable, followed by an integer pad
+        */ 
+        fprintf(Ffp,"    char version[8]; /* Version token */\n");
+        fprintf(Ffp,
+        "    int %s; /* Generalized Ntuple Multiplicity value */ \n",
+                                              nameTmpIndex);
+        fprintf(Ffp,
+        "    int padding; /* Padding for 64 bit architecture */ \n");
+        for (iv=0; iv< dNTu->numVariables; iv++) {
+           for (j=0; j<dNTu->numAvailable; j++)  
+                if (dNTu->varOrdering[j] == iv)  i = j; 
+           var = dNTu->variables[i];
+           kmode = 0; if (var->isFixedSize != True) kmode = 1;
+           if (var->description == NULL) descrTmp = nullDescr;
+                  else descrTmp = var->description;
+           tc = line;
+           if ((var->type != COMPLEX_NTU) &&
+               (var->type != DBL_COMPLEX_NTU)) { 
+                  sprintf(tc,"    %s %n", VarTypesNamesC[var->type], &l);
+                  tc +=l;            
+                  if ((var->numDim == 0) && (kmode ==0))
+                            sprintf(tc," %s; /* %s */",
+                                              var->name, descrTmp);
+                  else if (var->numDim == 0) {
+                        sprintf(tc," %s[%s]; /* %s */",
+                        var->name, nameMaxIndex, descrTmp); 
+                  } else { 
+                       sprintf(tc," %s%n",var->name, &l); tc+=l;
+                       if (kmode == 1) {
+                           sprintf(tc, "[%s]%n", nameMaxIndex, &l);
+                           tc +=l;
+                   }    
+                   for (j=var->numDim-1; j>-1; j--, tc+=l) 
+                             sprintf(tc,"[%d]%n", var->dimensions[j], &l); 
+                     
+                        sprintf (tc,"; /* %s */", descrTmp);
+                  }  
+               } else { /* got to convert to float or dbl */
+                    if (var->type == COMPLEX_NTU)
+                       sprintf(tc,"    float %n", &l);
+                       
+                     else if (var->type == DBL_COMPLEX_NTU)
+                       sprintf(tc,"    double %n", &l);
+                       
+                     tc +=l;            
+                     if ((var->numDim == 0) && (kmode ==0)) 
+                          sprintf(tc," %s[2]; /* %s */", var->name, descrTmp);
+                     else if (var->numDim == 0) {
+                       sprintf(tc," %s[%s][2]; /* %s */",
+                        var->name, nameMaxIndex, descrTmp); 
+                     } else { 
+                       sprintf(tc," %s%n",var->name, &l); tc+=l;
+                       if (kmode == 1) {
+                          sprintf(tc, "[%s]%n", nameMaxIndex, &l);
+                         tc +=l;
+                       }    
+                       for (j=var->numDim-1; j>-1; j--, tc+=l) 
+                             sprintf(tc,"[%d]%n", var->dimensions[j], &l); 
+                       sprintf (tc,"[2]; /* %s */", descrTmp);
+                    }
+               }
+               fprintf(Ffp,"%s\n", line);
+           }
+        fprintf(Ffp,"    int fence[2]; \n");
+        fprintf(Ffp,"} %s_struct; \n", nameCom);
+     }else { 
+     /*
+     ** The other type of organisation, using structure
+     */
+        fprintf(Ffp, "typedef struct _%s_v_struct{\n", nameCom);
+        for (iv=0; iv< dNTu->numVariables; iv++) {
+           for (j=0; j<dNTu->numAvailable; j++)  
+                if (dNTu->varOrdering[j] == iv)  i = j; 
+           var = dNTu->variables[i];
+           if (var->isFixedSize == False) {
+               tc = line;
+               if (var->type == COMPLEX_NTU)
+                       sprintf(tc,"    float %n", &l);
+               else if (var->type == DBL_COMPLEX_NTU)
+                       sprintf(tc,"    double %n", &l);
+               else 
+                     sprintf(tc,"    %s %n", VarTypesNamesC[var->type], &l);
+               tc +=l;            
+               sprintf(tc," %s%n",var->name, &l); tc+=l;
+               if (var->numDim != 0) {
+                    for (j=var->numDim-1; j>-1; j--, tc+=l) 
+                           sprintf(tc,"[%d]%n", var->dimensions[j], &l); 
+               }
+               if ((var->type == COMPLEX_NTU) ||
+                   (var->type == DBL_COMPLEX_NTU)) {
+                       sprintf (tc,"[2]%n",&l);
+                       tc += l;
+               }       
+               if (var->description == NULL) descrTmp = nullDescr;
+                    else descrTmp = var->description;
+               sprintf(tc,"; /* %s */%n", descrTmp, &l); tc += l;
+               fprintf(Ffp,"%s\n", line);
+            }
+        }
+        fprintf(Ffp,"} %s_v_struct; \n", nameCom);
+        fprintf(Ffp,"/* ----- */  \n");
+        /*
+        ** the mother structure now
+        */
+        fprintf(Ffp, "typedef struct _%s_struct{\n", nameCom);
+        fprintf(Ffp,"    char version[8]; /* Version token */\n");
+        fprintf(Ffp,
+        "    int %s; /* Generalized Ntuple Multiplicity value */ \n",
+                                              nameTmpIndex);
+        fprintf(Ffp,
+        "    int padding; /* Padding for 64 bit architecture */ \n");
+        for (iv=0; iv< dNTu->numVariables; iv++) {
+           for (j=0; j<dNTu->numAvailable; j++)  
+                if (dNTu->varOrdering[j] == iv)  i = j; 
+           var = dNTu->variables[i];
+           if (var->isFixedSize == True) {
+              tc = line;
+               if (var->type == COMPLEX_NTU)
+                       sprintf(tc,"    float %n", &l);
+               else if (var->type == DBL_COMPLEX_NTU)
+                       sprintf(tc,"    double %n", &l);
+               else 
+                     sprintf(tc,"    %s %n", VarTypesNamesC[var->type], &l);
+               tc +=l;            
+               sprintf(tc," %s%n",var->name, &l); tc+=l;
+               if (var->numDim != 0) {
+                    for (j=var->numDim-1; j>-1; j--, tc+=l) 
+                           sprintf(tc,"[%d]%n", var->dimensions[j], &l); 
+               }
+               if ((var->type == COMPLEX_NTU) ||
+                     (var->type == DBL_COMPLEX_NTU)) {
+                       sprintf (tc,"[2]%n",&l);
+                       tc += l;
+               }       
+               if (var->description == NULL) descrTmp = nullDescr;
+                    else descrTmp = var->description;
+               sprintf(tc,"; /* %s */%n", descrTmp, &l); tc += l;
+               fprintf(Ffp,"%s\n", line);
+            }
+        }
+        fprintf(Ffp,
+        "    %s_v_struct var[%s]; /* The array of substructures */\n",  
+                              nameCom, nameMaxIndex); 
+        fprintf(Ffp,"    int fence[2]; \n");
+        fprintf(Ffp,"} %s_struct; \n", nameCom);
+    }    
+    free(nameCom);
+    fclose(Ffp);
+    
+}
+
+void mcfioC_SetForSaveDecoding(int val)
+{
+     if(val != 0) McfNTuPleSaveDecoding = True;
+     else McfNTuPleSaveDecoding = False;
+}
+     
+static char *makeStructName(char *title, int orgStyle)
+{
+    char *out;
+    int i, l, nMax;
+    
+    l = strlen(title);
+    if (orgStyle  == PARALLEL_ARRAY_NTU) nMax = 23;  
+    else nMax = 21;
+    if (l > nMax) l = nMax;
+    out = (char *) malloc(sizeof(char) * (l+1));
+    strncpy(out, title, l); out[l]='\0';    
+    for (i=0; i<l; i++) if (out[i] == ' ') out[i] = '_';
+    return out;
+} 
+/*
+** CopyNtrim -  Copy "fromString" to a malloc'd new string,
+** 		trimming off leading and trailing spaces & tabs.
+**		The newly malloc'd string is returned.
+** 		If fromString is NULL, NULL is returned.
+*/
+static char *mcf_copyNtrim(char *fromString)
+{
+    char *c, *toString;
+    int len, i;
+    
+    if (fromString == NULL)
+    	return NULL;
+    toString = (char *) malloc(strlen(fromString)+1);
+    
+    /* Find the first non-white character */
+    for (c=fromString; *c == ' ' || *c == '\t'; c++);
+
+    /* Copy the remainder of fromString to toString */
+    strcpy(toString, c);
+    
+    /* Remove trailing spaces and tabs by converting to nulls */
+    len = strlen(toString);
+    if (len == 0)			/* special case for empty strings */
+    	return toString;
+    for (i = len-1; i >= 0; --i) {
+    	if (isspace(toString[i]))
+    	    toString[i] = '\0';
+    	else
+    	    break;
+    }
+    return toString;
+}    
+     
+     
+     
Index: /trunk/Utilities/mcfio/mcf_NTuIOFiles.h
===================================================================
--- /trunk/Utilities/mcfio/mcf_NTuIOFiles.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_NTuIOFiles.h	(revision 3)
@@ -0,0 +1,15 @@
+/*******************************************************************************
+*									       *
+* mcf_NTuIOFiles.h -- Utilities to manipulate files within the MCFIO Gen.      *
+*        				Ntuple schema                          *
+*									       *
+*	P. Lebrun, September 1995.					       *
+*									       *
+*******************************************************************************/
+int mcfioC_DeclareNtuple(int uid, char *title, char *category, 
+                                int stream, char *filename);
+int mcfioC_EndDeclNTuples(int stream);                                
+nTuDDL *mcf_GetFileNTuDDL(char*filename);
+void    mcf_ComputeNTuOffsets(nTuDDL *ddl); 
+void    mcf_ComputeNTuLengths(nTuDDL *ddl); 
+void    mcf_ComposeDoth(descrGenNtuple *dNtu, char *filename);
Index: /trunk/Utilities/mcfio/mcf_NTuIOUtils.c
===================================================================
--- /trunk/Utilities/mcfio/mcf_NTuIOUtils.c	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_NTuIOUtils.c	(revision 3)
@@ -0,0 +1,290 @@
+/*******************************************************************************
+*									       *
+* mcf_NTuIOUtils.c -- Utilities to manipulate files within the MCFIO Gen.      *
+*        				Ntuple schema                          *
+*									       *
+*	P. Lebrun, September 1995.					       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <limits.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <rpc/xdr.h>
+#include "mcf_nTupleDescript.h"
+#include "mcf_xdr.h"
+#include "mcfio_Dict.h"
+#include "mcf_NTuIOFiles.h"
+#include "mcf_NTuIOUtils.h"
+#include "mcf_ntubld_db.h"
+#ifndef False
+#define False 0
+#endif
+#ifndef True
+#define True 1
+#endif
+
+extern nTuDDL **NTuDDLList;
+extern int NumOfNTuples;
+
+nTuDDL *mcf_GetNTuByPtrID(int id)
+{
+    int **ip;
+    
+    if ( (id < 1) || (id > NumOfNTuples)) return NULL;
+    ip = (int **) NTuDDLList;
+    ip += (id-1);
+    return (nTuDDL *) *ip; 
+}
+     
+nTuDDL *mcf_GetNTuByStreamID(int stream, int id)
+{
+     int i, num;
+     nTuDDL *ddl;
+     
+     for (i=0, num=0; i<NumOfNTuples; i++) { 
+          ddl = NTuDDLList[i];
+          if ((ddl->streamId == stream) && (ddl->seqNTuId == id)) return ddl;
+     }
+     return NULL;
+}   
+int mcf_NTuId(int uid, char *category)
+/* 
+	uid		Unique User id 
+	category	Category name, must be an exact match
+
+	Returns:	Macfio_Ntuple id, or -1 if no items matched, or if 
+			Category is illegal..
+*/
+{
+	int i, j, **ip;
+	nTuDDL *item;
+	char *cat;
+	
+     if (!mcf_CheckValidCat(category, FALSE))  return -1;
+     ip = (int **) NTuDDLList;
+     cat = mcf_ValidStr(category, NTU_MAX_CATEGORY_LENGTH, "category");
+     for (i=0; i< NumOfNTuples; i++, ip++) {
+	 item = (nTuDDL *) *ip;
+	 if (item->uid == uid) { /* Look first at uid, if match, */
+	         		    /* Confirm with Category */
+	    if ((category == NULL) && (item->category == NULL)) 
+	      				return (item->id);
+	    if (strcmp(category, item->category) == 0)
+	    				return (item->id);
+            j = strspn(category, " ");	
+	    if (strcmp((category+j), item->category) == 0)
+	                                return (item->id); 
+	 }
+     }
+     return -1;
+}
+
+int mcfioC_GetNTupleIds(int stream, int *ids, int max)
+{
+     int i, num;
+     nTuDDL *ddl;
+     
+     for (i=0, num=0; i<NumOfNTuples; i++) { 
+          ddl = NTuDDLList[i];
+          if (ddl->streamId == stream) {
+              if (num < max ) ids[num] = ddl->id;
+              num++;
+          }
+     }
+     return num;
+}   
+
+int mcfioC_GetNTupleUID(int stream, int id)
+{
+   nTuDDL *ddl = mcf_GetNTuByStreamID(stream, id);
+   return ddl->uid;
+}
+
+void mcfioC_GetNTupleCategory(int stream, int id, char **answer)
+{
+   nTuDDL *ddl = mcf_GetNTuByStreamID(stream, id);
+   *answer = ddl->category;
+}
+ 
+void mcfioC_GetNTupleTitle(int stream, int id, char **answer)
+{
+   nTuDDL *ddl = mcf_GetNTuByStreamID(stream, id);
+   *answer = ddl->title;
+}
+
+void mcfioC_GetNTupleName(int stream, int id, char **answer)
+{
+   nTuDDL *ddl = mcf_GetNTuByStreamID(stream, id);
+   if (ddl->reference == NULL) 
+       *answer = ddl->descrNtu->title;
+   else *answer = ddl->reference->descrNtu->title;    
+}
+
+/*
+** Copy utility routine for a General Ntuple Variable descriptor d/s
+** It is the responsability of the usr to allocate memory for the 
+** structure where data will be copied to.
+*/           
+void CopyVarGenNtuple(varGenNtuple *vFrom, varGenNtuple *vTo)
+{
+    int i, ll;
+
+    if ((vTo == NULL)  || (vFrom == NULL)) return;
+    vTo->nameBlank = vFrom->nameBlank;
+    if (vTo->name != NULL) {
+        free(vTo->name);
+        vTo->name = NULL;
+    }
+    if (vFrom->name != NULL) {
+        ll = (1 + strlen(vFrom->name));
+        vTo->name = 
+           (char *) malloc(sizeof(char) * ll);
+        strcpy(vTo->name, vFrom->name);
+    }
+    if (vTo->description != NULL) {
+         free(vTo->description);
+         vTo->description = NULL;
+    }
+    if (vFrom->description != NULL) {
+        vTo->description = 
+           (char *) malloc(sizeof(char) * (1 + strlen(vFrom->description)));
+        strcpy(vTo->description, vFrom->description);
+    }
+    vTo->type = vFrom->type;
+    vTo->isFixedSize = vFrom->isFixedSize;
+    vTo->numDim = vFrom->numDim;
+    if (vFrom->numDim > 0)  {
+           for (i=0; i<vFrom->numDim; i++)
+              vTo->dimensions[i] = vFrom->dimensions[i]; 
+    }
+    vTo->offset = vFrom->offset;
+    vTo->offsetXDR = vFrom->offsetXDR;
+}
+/*
+** insert this ddl into the Global List, expand the list if need be.
+** Also increment the number of NTuples defined (don't do it twice!). 
+*/
+void AddNTuDDLtoList(nTuDDL *ddl)
+{
+    int **ipo;
+    
+    NumOfNTuples++;
+    ddl->id = NumOfNTuples;
+    /*
+    ** insert this ddl into the Global List, expand the list if need be
+    */
+    if( (NumOfNTuples - (NumOfNTuples/NTU_START_LIST_SIZE)*NTU_START_LIST_SIZE)
+                     == 1 && (NumOfNTuples != 1)) {
+            ipo = (int **) NTuDDLList;
+    	    NTuDDLList  = (nTuDDL **) malloc(sizeof(int *)*
+              ((NumOfNTuples/NTU_START_LIST_SIZE + 1)*NTU_START_LIST_SIZE));
+            memcpy(NTuDDLList, ipo, (sizeof(int *)*(NumOfNTuples-1)));
+    	    free (ipo);
+    }
+    NTuDDLList[NumOfNTuples-1] = ddl;
+            
+}
+/*
+** Free the memory for a Ntuple Data Descrp. Lang (DDL).  
+*/
+void DestroyNTuDDL(nTuDDL *ddl)
+{
+   if (ddl->title != NULL) free(ddl->title);
+   if (ddl->category != NULL) free(ddl->category);
+   if (ddl->dbinFileName != NULL) free(ddl->dbinFileName);
+   DestroyGenNtuple(ddl->descrNtu);
+   free(ddl);
+} 
+/*
+** Free the memory for a Description NTuple
+** Note : the pointer to adrresses are lost, the user will have to give 
+** them to this application back..
+*/
+void DestroyGenNtuple(descrGenNtuple *dNTu)
+{
+    int i;
+
+    if (dNTu == NULL) return;
+    if (dNTu->title != NULL) free(dNTu->title);
+    if (dNTu->description != NULL) free(dNTu->description);
+    if (dNTu->varOrdering != NULL) free(dNTu->varOrdering);
+    if (dNTu->subOffset != NULL) free(dNTu->subOffset);
+    if (dNTu->subXDROffset != NULL) free(dNTu->subXDROffset);
+    for (i=0; i<dNTu->numAvailable; i++)
+         DestroyVarGenNtuple(dNTu->variables[i]);
+    free(dNTu->variables);
+    free(dNTu);     
+}    
+
+
+void DestroyVarGenNtuple(varGenNtuple *var)
+{
+
+    if (var == NULL) return;
+    if (var->name != NULL) free(var->name);
+    if (var->description != NULL) free(var->description);
+    free(var);
+}    
+/*
+ * ValidStr - Validate strings supplied by user
+ *
+ *	      returns: pointer to valid same or new truncated string
+ *
+ *  Note: ** copy string returned, if needed, before calling ValidStr again **
+ */
+char *mcf_ValidStr(char *string, int max_length, char *strKind)
+{
+    static char str[NTU_MAX_CATEGORY_LENGTH+1];	     /* make longest string */
+    static char str1[1] = "";
+    
+    if (string == NULL)
+    	return str1;			   /* return empty string	    */
+    if (strlen(string) <= max_length)
+    	return string;			   /* return pointer to same string */
+    fprintf(stderr,
+      "Mcfio_Ntuple: Error. Specified %s string is too long, truncating\n     ->%s\n",
+    	 strKind, string);
+    memset(str, 0, NTU_MAX_CATEGORY_LENGTH+1);
+    return strncpy(str, string, max_length); /* return ptr to trunc. string */
+}
+/*
+** Based on the HistoScope Check Category 
+*/      
+int mcf_CheckValidCat(char *category, int dotDotDot)
+{
+    static char validChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+abcdefghijklmnopqrstuvwxyz1234567890/~!@#$%^&*()_+=-`\"\'\t?><,. ";
+    char *strDots, *error = NULL;
+    int len;
+    
+    if (category == NULL)
+    	return 1;
+    len = strlen(category);
+    strDots = strstr(category, "...");
+    if (len >= NTU_MAX_CATEGORY_LENGTH)
+    	error = "is too long";
+    else if (strspn(category, validChars) != len)
+    	error = "contains invalid characters";
+    else if (strstr(category, "//") != NULL)
+    	error = "contains \"//\"";
+    else if (category[0] == '/')
+    	error = "contains leading slash";
+    else if (category[len-1] == '/')
+    	error = "contains trailing slash";
+    else if ((dotDotDot == 0 && strDots != NULL) 
+    	  || (dotDotDot != 0 && strDots != NULL && strDots != category + len-3))
+    	error = "contains invalid \"...\"";
+    	
+    if (error != NULL) {
+    	fprintf(stderr, "Error in declared category %s: %s\n",
+    		error, category);
+    	return 0;
+    } else {
+    	return (strDots == NULL ? 1 : -1);
+    }
+}
+
Index: /trunk/Utilities/mcfio/mcf_NTuIOUtils.h
===================================================================
--- /trunk/Utilities/mcfio/mcf_NTuIOUtils.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_NTuIOUtils.h	(revision 3)
@@ -0,0 +1,24 @@
+/*******************************************************************************
+*									       *
+* mcf_NTuIOUtil.h -- Utilities to manipulate files within the MCFIO Gen.      *
+*        				Ntuple schema                          *
+*									       *
+*	P. Lebrun, October 1995.					       *
+*									       *
+*******************************************************************************/
+nTuDDL *mcf_GetNTuByPtrID(int id);
+nTuDDL *mcf_GetNTuByStreamID(int stream, int id);
+int mcf_CheckValidCat(char *category, int dotDotDot);
+char *mcf_ValidStr(char *string, int max_length, char *strKind);
+int mcf_NTuId(int uid, char *category);
+int mcfioC_GetNTupleIds(int stream, int *ids, int max);
+int mcfioC_GetNTupleUID(int stream, int id);
+void mcfioC_GetNTupleCategory(int stream, int id, char **answer);
+void mcfioC_GetNTupleTitle(int stream, int id, char **answer);
+void mcfioC_GetNTupleName(int stream, int id, char **answer);
+void AddNTuDDLtoList(nTuDDL *ddl);
+void DestroyNTuDDL(nTuDDL *ddl);
+void DestroyVarGenNtuple(varGenNtuple *var);
+void CopyVarGenNtuple(varGenNtuple *vFrom, varGenNtuple *vTo);
+void DestroyGenNtuple(descrGenNtuple  *dNTu);
+void mcfioC_SetForSaveDecoding(int val);
Index: /trunk/Utilities/mcfio/mcf_evt_xdr.c
===================================================================
--- /trunk/Utilities/mcfio/mcf_evt_xdr.c	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_evt_xdr.c	(revision 3)
@@ -0,0 +1,1569 @@
+/*******************************************************************************
+*									       *
+* mcf_evt_xdr.c -- XDR Utility routines for the McFast Monte-Carlo             *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Paul Lebrun						       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <rpc/xdr.h>
+#include <limits.h>
+#ifdef SUNOS
+#include <floatingpoint.h>
+#else /* SUNOS */
+#include <float.h>
+#endif /* SUNOS */
+#include <stdlib.h>
+#include <time.h>
+#include "mcf_nTupleDescript.h"
+#include "mcf_xdr.h"
+#include "mcf_xdr_Ntuple.h"
+#include "mcf_NTuIOFiles.h"
+#include "mcf_NTuIOUtils.h"
+#include "mcfio_Util1.h"
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+
+static bool_t xdr_mcfast_NTuDDL(XDR *xdrs, char *version, nTuDDL *ddl);
+static bool_t xdr_mcfast_descrNTU(XDR *xdrs, char *version,
+                                    descrGenNtuple *dNTu);
+static bool_t xdr_mcfast_varDescrNTU(XDR *xdrs, char *version,
+                                    varGenNtuple *var);
+
+extern nTuDDL **NTuDDLList;
+extern int NumOfNTuples;
+
+bool_t xdr_mcfast_generic(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version, char** data)
+{
+/*  Translate a Generic mcfFast block. This module will allocate memory 
+    for the data. */
+        
+    unsigned int nn;
+    
+    if (xdrs->x_op == XDR_ENCODE) {
+      nn = strlen(*data);  
+      *ntot = 12+nn;
+       strcpy(*version, "0.00");
+       } else if (xdrs->x_op == XDR_FREE) {
+          free(*data);
+          return 1;
+       }
+      
+     if (( xdr_int(xdrs, blockid) && 
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH)) 
+     	         == FALSE) return FALSE;
+     nn = *ntot - 12;	      
+     if (xdrs->x_op == XDR_DECODE) *data = NULL; 
+     return (xdr_string(xdrs, data, nn));     	
+}   
+
+
+bool_t xdr_mcfast_headerBlock(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version)
+{
+/*  Translate a Generic mcfFast block. This module will allocate memory 
+    for the data. */
+
+    if (xdrs->x_op == XDR_ENCODE) {
+       printf ("xdr_mcfast_headerBlock: Internal error \n");
+       return FALSE;
+       }
+      
+     return ( xdr_int(xdrs, blockid) && 
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH));
+}   
+bool_t xdr_mcfast_fileheader(XDR *xdrs, int *blockid,
+ 		 int *ntot, char** version, mcfxdrFileHeader **mcf,
+ 		  int streamId)
+{
+/*  Translate a mcf FileHeader block.  This subroutine will allocate
+	the memory needed if the stream is DECODE */
+        
+    int i;
+    unsigned int nn, oldNumOfNTuples;
+    char **ctmp;
+    char *atmp, *btmp, *dtmp;
+    int *itmp;
+    mcfxdrFileHeader *mcftmp;
+    nTuDDL *ddl;
+    float fv;
+    
+    
+    mcftmp = *mcf;
+    if (xdrs->x_op == XDR_ENCODE) {
+      *ntot = sizeof(mcfxdrFileHeader) - sizeof(int *) - sizeof(char **) 
+              + 2 * sizeof(int) * mcftmp->nBlocks 
+              - sizeof(char) * MCF_XDR_F_TITLE_LENGTH
+              + sizeof(char) * strlen(mcftmp->title) + 
+              + sizeof(char) * strlen(mcftmp->comment) ;
+      for (i=0, ctmp = mcftmp->blockNames; 
+             i< mcftmp->nBlocks; i++, ctmp++) *ntot += strlen(*ctmp);  
+       strcpy(*version, "2.01");
+     }  else if (xdrs->x_op == XDR_FREE) {
+          mcfioC_Free_FileHeader(mcf);
+          return 1;
+     } else if((xdrs->x_op == XDR_DECODE) && (*mcf == NULL)) {
+          mcftmp = (mcfxdrFileHeader *) malloc(sizeof(mcfxdrFileHeader));
+          *mcf = mcftmp;
+     } 
+        
+
+       
+     if (( xdr_int(xdrs, blockid) && 
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH))
+     	                  == FALSE) return FALSE;
+     
+     /*
+     ** Code valid for version 1.00
+     */
+     if (strcmp(*version, "1.00") == 0) {
+         atmp = &(mcftmp->title[0]);
+         btmp = &(mcftmp->comment[0]);
+         dtmp = &(mcftmp->date[0]);
+     	      
+        if ((xdr_string(xdrs, &atmp, MCF_XDR_F_TITLE_LENGTH) &&
+             xdr_string(xdrs,&btmp, MCF_XDR_F_TITLE_LENGTH) &&
+             xdr_string(xdrs,&dtmp, 30)) == FALSE) return FALSE;
+	
+        if ((xdr_u_int(xdrs,&(mcftmp->numevts_expect)) &&
+             xdr_u_int(xdrs,&(mcftmp->numevts)) &&
+             xdr_u_int(xdrs,&(mcftmp->firstTable)) &&
+             xdr_u_int(xdrs,&(mcftmp->dimTable)) &&
+             xdr_u_int(xdrs,&(mcftmp->nBlocks))) == FALSE) return FALSE;
+        if(xdrs->x_op == XDR_DECODE) {
+           mcftmp->blockIds = (int *) malloc(sizeof(int) * mcftmp->nBlocks);
+           mcftmp->blockNames = 
+           	(char**) malloc(sizeof(char *) * mcftmp->nBlocks);
+           for (i=0; i<mcftmp->nBlocks; i++) 
+                mcftmp->blockNames[i] =
+                  (char *) malloc(sizeof(char) * (MCF_XDR_B_TITLE_LENGTH +1));
+        }
+        itmp = mcftmp->blockIds;
+        if (xdrs->x_op == XDR_ENCODE) nn = mcftmp->nBlocks;
+	if (xdr_array(xdrs, (char **) &itmp, &nn, 
+	             mcftmp->nBlocks, sizeof(int), (void *) xdr_int) == FALSE) 
+	              return FALSE;
+	for (i=0; i<mcftmp->nBlocks; i++) {
+	       if (xdr_string(xdrs, &(mcftmp->blockNames[i]), 
+	               MCF_XDR_B_TITLE_LENGTH) == FALSE) return FALSE; 
+	    }	              
+	 mcftmp->nNTuples = 0;  
+     } else if (strncmp(*version, "2.",2) == 0){
+         sscanf(*version, "%f", &fv);
+     /*
+     ** Code valid for version 2.xx, adding the NTuples
+     */
+         atmp = &(mcftmp->title[0]);
+         btmp = &(mcftmp->comment[0]);
+         dtmp = &(mcftmp->date[0]);
+     	      
+        if ((xdr_string(xdrs, &atmp, MCF_XDR_F_TITLE_LENGTH) &&
+             xdr_string(xdrs,&btmp, MCF_XDR_F_TITLE_LENGTH) &&
+             xdr_string(xdrs,&dtmp, 30)) == FALSE) return FALSE;
+             
+         if (fv == 2.) strcpy(mcftmp->closingDate, mcftmp->date);
+         else {
+             atmp = &(mcftmp->closingDate[0]);
+            if (xdr_string(xdrs, &atmp, 30) == FALSE) return FALSE; 
+     	}      
+        if ((xdr_u_int(xdrs,&(mcftmp->numevts_expect)) &&
+             xdr_u_int(xdrs,&(mcftmp->numevts)) &&
+             xdr_u_int(xdrs,&(mcftmp->firstTable)) &&
+             xdr_u_int(xdrs,&(mcftmp->dimTable)) &&
+             xdr_u_int(xdrs,&(mcftmp->nBlocks)) &&
+             xdr_u_int(xdrs,&(mcftmp->nNTuples))) == FALSE) return FALSE;
+        if((xdrs->x_op == XDR_DECODE) && (mcftmp->nBlocks > 0)) {
+           mcftmp->blockIds = (int *) malloc(sizeof(int) * mcftmp->nBlocks);
+           mcftmp->blockNames = 
+           	(char**) malloc(sizeof(char *) * mcftmp->nBlocks);
+           for (i=0; i<mcftmp->nBlocks; i++) 
+                mcftmp->blockNames[i] =
+                  (char *) malloc(sizeof(char) * (MCF_XDR_B_TITLE_LENGTH +1));
+        }
+        itmp = mcftmp->blockIds;
+        if (xdrs->x_op == XDR_ENCODE) nn = mcftmp->nBlocks;
+        if (mcftmp->nBlocks > 0) {
+	    if (xdr_array(xdrs, (char **) &itmp, &nn, 
+	             mcftmp->nBlocks, sizeof(int), (void *) xdr_int) == FALSE) 
+	              return FALSE;
+	    for (i=0; i<mcftmp->nBlocks; i++) {
+	          if (xdr_string(xdrs, &(mcftmp->blockNames[i]), 
+	               MCF_XDR_B_TITLE_LENGTH) == FALSE) return FALSE; 
+	    }
+	  } else {
+	   mcftmp->blockNames = NULL;
+	   mcftmp->blockIds = NULL;
+	}
+	/*
+	** Now take care of the Ntuples
+	*/
+        if((xdrs->x_op == XDR_DECODE) && (mcftmp->nNTuples > 0)) {
+	   oldNumOfNTuples = NumOfNTuples;
+           for (i=0; i<mcftmp->nNTuples; i++) {
+                ddl = (nTuDDL * ) malloc(sizeof(nTuDDL));
+                AddNTuDDLtoList(ddl);
+                if (xdr_mcfast_NTuDDL(xdrs, *version, ddl) == FALSE) 
+                                                        return FALSE;
+           }
+        }  else if ((xdrs->x_op == XDR_ENCODE)  && (mcftmp->nNTuples > 0)) {  
+            for (i=0; i<NumOfNTuples; i++) {
+                ddl =mcf_GetNTuByPtrID(i+1);
+                if ((ddl->streamId == streamId) &&  
+                    (xdr_mcfast_NTuDDL(xdrs, *version, ddl) == FALSE)) 
+                                                        return FALSE;
+           }                                             
+       }                                                  
+		              
+     } else return FALSE; /* Other Futur version encoded here. */
+     return TRUE;
+     	      
+}   
+
+bool_t xdr_mcfast_eventtable(XDR *xdrs, int *blockid,
+ 		 int *ntot, char** version, mcfxdrEventTable **mcf)
+{
+/*  Translate a mcf EventTable block.  This subroutine will allocate
+	the memory needed if the stream is DECODE */
+        
+    int *idat;
+    unsigned int nn, nnold, *uidat;
+    mcfxdrEventTable *mcftmp;
+    
+    
+    mcftmp = *mcf;
+    if (xdrs->x_op == XDR_ENCODE) {
+      *ntot = sizeof(mcfxdrEventTable) + 4 * sizeof(int)* mcftmp->dim
+              + sizeof(unsigned int)* mcftmp->dim - 2 * sizeof(int)
+              - 4 * sizeof(int *) - sizeof(u_int *);
+       strcpy(*version, "1.00");
+     }  else if (xdrs->x_op == XDR_FREE) {
+          mcfioC_Free_EventTable(mcf);
+          return 1;
+     } else if((xdrs->x_op == XDR_DECODE) && ( mcftmp == NULL)) {
+          mcftmp = (mcfxdrEventTable *) malloc(sizeof(mcfxdrEventTable));
+          *mcf = mcftmp;
+     } 
+        
+
+       
+     if (( xdr_int(xdrs, blockid) && 
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH)) 
+     	                 == FALSE) return FALSE;
+     
+     /*
+     ** Code valid for version 1.00
+     */
+     if (strcmp(*version, "1.00") == 0) {
+     	      
+        if((xdrs->x_op == XDR_DECODE) && (mcftmp->evtnums != NULL))
+             nnold = mcftmp->previousnumevts;
+          else nnold = 0;
+        idat = &mcftmp->nextLocator;
+        uidat = (u_int *) &mcftmp->numevts;  
+        if ((xdr_int(xdrs,idat) && xdr_u_int(xdrs,uidat )) == FALSE)
+                  return FALSE; 
+        if(xdrs->x_op == XDR_DECODE) {
+           if ((mcftmp->evtnums == NULL) || (mcftmp->numevts > nnold)) {
+           if (mcftmp->evtnums != NULL) {
+            /*
+            ** I don't trust realloc.. just alloc again.. 
+            */
+            free(mcftmp->evtnums); free(mcftmp->storenums); 
+            free(mcftmp->runnums); free(mcftmp->trigMasks);
+            free(mcftmp->ptrEvents);
+            }  
+           mcftmp->evtnums = (int *) malloc(sizeof(int) * mcftmp->dim);
+           mcftmp->storenums = (int *) malloc(sizeof(int) * mcftmp->dim);
+           mcftmp->runnums = (int *) malloc(sizeof(int) * mcftmp->dim);
+           mcftmp->trigMasks = (int *) malloc(sizeof(int) * mcftmp->dim);
+           mcftmp->ptrEvents = 
+            (unsigned int *) malloc(sizeof(unsigned int) * mcftmp->dim);
+            mcftmp->previousnumevts = mcftmp->dim;
+           }
+        }
+        if (xdrs->x_op == XDR_ENCODE) nn = mcftmp->dim;
+        idat = mcftmp->evtnums;
+	if (xdr_array(xdrs, (char **) &idat, &nn, 
+	              mcftmp->dim, sizeof(int), (void *) xdr_int) == FALSE) 
+	              return FALSE;
+        idat = mcftmp->storenums;
+	if (xdr_array(xdrs, (char **) &idat, &nn, 
+	              mcftmp->dim, sizeof(int), (void *) xdr_int) == FALSE) 
+	              return FALSE;
+        idat = mcftmp->runnums;
+	if (xdr_array(xdrs, (char **) &idat, &nn, 
+	              mcftmp->dim, sizeof(int), (void *) xdr_int) == FALSE) 
+	              return FALSE;
+        idat = mcftmp->trigMasks;
+	if (xdr_array(xdrs, (char **) &idat, &nn, 
+	              mcftmp->dim, sizeof(int), (void *) xdr_int) == FALSE) 
+	              return FALSE;
+        uidat = mcftmp->ptrEvents;
+	if (xdr_array(xdrs, (char **) &uidat, &nn, 
+	              mcftmp->dim, sizeof(int), (void *) xdr_u_int) == FALSE) 
+	              return FALSE;
+     } else return FALSE; /* Future version encoded here. */
+     return TRUE;
+     	      
+}
+   
+bool_t xdr_mcfast_seqheader(XDR *xdrs, int *blockid,
+ 		 int *ntot, char** version, mcfxdrSequentialHeader **mcf)
+{
+/*  Translate a mcf EventTable block.  This subroutine will allocate
+	the memory needed if the stream is DECODE */
+        
+    mcfxdrSequentialHeader *mcftmp;
+    
+    
+    if (xdrs->x_op == XDR_ENCODE) {
+      mcftmp = *mcf;
+      *ntot = sizeof(mcfxdrSequentialHeader);
+       strcpy(*version, "1.00");
+     }  else if (xdrs->x_op == XDR_FREE) {
+          mcfioC_Free_SeqHeader(mcf);
+          return 1;
+     } else if(xdrs->x_op == XDR_DECODE) {
+          if (*mcf == NULL) {
+              mcftmp = (mcfxdrSequentialHeader *) 
+                        malloc(sizeof(mcfxdrSequentialHeader));
+              *mcf = mcftmp;
+          } else mcftmp = *mcf;
+          
+     } 
+        
+
+       
+/*     if (( xdr_int(xdrs, blockid) && 
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH)) 
+     	                 == FALSE) return FALSE;
+*/
+      if (xdr_int(xdrs,blockid) == FALSE) return FALSE;
+      if (xdr_int(xdrs,ntot) == FALSE) return FALSE; 
+      if (xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH) 
+     	                 == FALSE) return FALSE;    
+     /*
+     ** Code valid for version 1.00
+     */
+     if (strcmp(*version, "1.00") == 0) {
+     	      
+        if (xdr_u_int(xdrs,&(mcftmp->nRecords)) == FALSE) return FALSE; 
+     } else return FALSE; /* Futur version encoded here. */
+     return TRUE;
+     	      
+}
+
+bool_t xdr_mcfast_eventheader(XDR *xdrs, int *blockid,
+ 		 int *ntot, char** version, mcfxdrEventHeader **mcf)
+{
+/*  Translate a mcf Event header block.  This subroutine will allocate
+	the memory needed if the stream is DECODE */
+        
+    int *itmp;
+    unsigned int nn, nnold, nNTuOld, *uitmp;
+    mcfxdrEventHeader *mcftmp;
+    
+    
+    mcftmp = *mcf;
+    if (xdrs->x_op == XDR_ENCODE) {
+      *ntot = sizeof(mcfxdrEventHeader)
+              + sizeof(unsigned int)* mcftmp->nBlocks
+              + sizeof(int ) * mcftmp->nBlocks 
+              - sizeof(int *)  - sizeof(u_int *) ;
+       strcpy(*version, "2.00");
+     }  else if (xdrs->x_op == XDR_FREE) {
+          mcfioC_Free_EventHeader(mcf);
+          return 1;
+     } else if((xdrs->x_op == XDR_DECODE) && (mcftmp == NULL)) {
+          mcftmp =
+           (mcfxdrEventHeader *) malloc(sizeof(mcfxdrEventHeader));
+          *mcf = mcftmp;
+          mcftmp->blockIds = NULL;
+          mcftmp->ptrBlocks = NULL;
+     } 
+        
+
+       
+     if (( xdr_int(xdrs, blockid) && 
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH)) 
+     	                  == FALSE) return FALSE;
+     
+     /*
+     ** Code valid for version 1.00
+     */
+     if (strcmp(*version, "1.00") == 0) {
+        if((xdrs->x_op == XDR_DECODE) && (mcftmp->blockIds != NULL))
+             nnold = mcftmp->dimBlocks;  
+     	else nnold = 0;      
+        if ((xdr_int(xdrs,&(mcftmp->evtnum)) &&
+             xdr_int(xdrs,&(mcftmp->storenum)) &&
+             xdr_int(xdrs,&(mcftmp->runnum)) &&
+             xdr_int(xdrs,&(mcftmp->trigMask)) &&
+             xdr_u_int(xdrs,&(mcftmp->nBlocks)) &&
+             xdr_u_int(xdrs,&(mcftmp->dimBlocks))) == FALSE) return FALSE; 
+        if(xdrs->x_op == XDR_DECODE) {
+           if ((mcftmp->blockIds == NULL) || (mcftmp->dimBlocks > nnold)) {
+           if (mcftmp->blockIds != NULL) {
+            /*
+            ** I don't trust realloc.. just alloc again.. 
+            */
+            free(mcftmp->blockIds); free(mcftmp->ptrBlocks); 
+            }  
+           mcftmp->blockIds =
+             (int *) malloc(sizeof(unsigned int) * mcftmp->dimBlocks);
+           mcftmp->ptrBlocks =
+             (unsigned int *) malloc(sizeof(unsigned int) * mcftmp->dimBlocks);
+           }
+        }
+        if (xdrs->x_op == XDR_ENCODE)  nn = mcftmp->dimBlocks;
+        itmp = mcftmp->blockIds;
+	if (xdr_array(xdrs, (char **) &itmp, &nn, 
+	              mcftmp->dimBlocks, sizeof(int), (void *) xdr_int) == FALSE) 
+	              return FALSE;
+	uitmp = mcftmp->ptrBlocks;              
+	if (xdr_array(xdrs, (char **) &uitmp, &nn, 
+	              mcftmp->dimBlocks, sizeof(u_int), (void *) xdr_u_int) == FALSE) 
+	              return FALSE;
+     } else if (strcmp(*version, "2.00") == 0) {
+        if (xdrs->x_op == XDR_DECODE) {
+           nnold = 0;
+           if (mcftmp->blockIds != NULL)  nnold = mcftmp->dimBlocks;
+           nNTuOld = 0;
+           if (mcftmp->nTupleIds != NULL)  nNTuOld = mcftmp->dimNTuples;
+        }  
+        if ((xdr_int(xdrs,&(mcftmp->evtnum)) &&
+             xdr_int(xdrs,&(mcftmp->storenum)) &&
+             xdr_int(xdrs,&(mcftmp->runnum)) &&
+             xdr_int(xdrs,&(mcftmp->trigMask)) &&
+             xdr_u_int(xdrs,&(mcftmp->nBlocks)) &&
+             xdr_u_int(xdrs,&(mcftmp->dimBlocks)) &&
+             xdr_u_int(xdrs,&(mcftmp->nNTuples)) &&
+             xdr_u_int(xdrs,&(mcftmp->dimNTuples))) == FALSE) return FALSE;
+        if(xdrs->x_op == XDR_DECODE) {
+           if ((mcftmp->blockIds == NULL) || (mcftmp->dimBlocks > nnold)) {
+           if (mcftmp->blockIds != NULL) { 
+               free(mcftmp->blockIds);
+               free(mcftmp->ptrBlocks);
+           }     
+           mcftmp->blockIds =
+             (int *) malloc(sizeof(unsigned int) * mcftmp->dimBlocks);
+           mcftmp->ptrBlocks =
+             (unsigned int *) malloc(sizeof(unsigned int) * mcftmp->dimBlocks);
+           }
+           if ((mcftmp->nTupleIds == NULL) || (mcftmp->dimNTuples > nNTuOld)) {
+           if (mcftmp->nTupleIds != NULL) { 
+               free(mcftmp->nTupleIds);
+               free(mcftmp->ptrNTuples);
+           }     
+           mcftmp->nTupleIds =
+             (int *) malloc(sizeof(unsigned int) * mcftmp->dimNTuples);
+           mcftmp->ptrNTuples =
+             (unsigned int *) malloc(sizeof(unsigned int) * mcftmp->dimNTuples);
+           }
+        }
+        if (mcftmp->dimBlocks > 0) {
+            if (xdrs->x_op == XDR_ENCODE)  nn = mcftmp->dimBlocks;
+            itmp = mcftmp->blockIds;
+	    if (xdr_array(xdrs, (char **) &itmp, &nn, 
+	              mcftmp->dimBlocks, sizeof(int), (void *) xdr_int) == FALSE) 
+	              return FALSE;
+	    uitmp = mcftmp->ptrBlocks;              
+	    if (xdr_array(xdrs, (char **) &uitmp, &nn, 
+	              mcftmp->dimBlocks, sizeof(u_int), (void *) xdr_u_int) == FALSE) 
+	              return FALSE;
+        }
+        if (mcftmp->dimNTuples > 0) {
+            if (xdrs->x_op == XDR_ENCODE)  nn = mcftmp->dimNTuples;
+            itmp = mcftmp->nTupleIds;
+	    if (xdr_array(xdrs, (char **) &itmp, &nn, 
+	              mcftmp->dimNTuples, sizeof(int), (void *) xdr_int) == FALSE) 
+	              return FALSE;
+	    uitmp = mcftmp->ptrNTuples;              
+	    if (xdr_array(xdrs, (char **) &uitmp, &nn, 
+	              mcftmp->dimNTuples, sizeof(u_int), (void *) xdr_u_int) == FALSE) 
+	              return FALSE;
+	}              
+     } else 
+      return FALSE; /* Futur version encoded here. */
+     return TRUE;
+     	      
+}
+
+static bool_t xdr_mcfast_NTuDDL(XDR *xdrs, char *version, nTuDDL *ddl)
+{
+    int i, nc_title, nc_category, idRef;
+    descrGenNtuple *dNTu;
+    
+    
+    /*
+    ** This is the first version, let us not get too compilcated..
+    */
+    if (xdrs->x_op == XDR_ENCODE) {
+           nc_title = strlen(ddl->title);
+           nc_category = strlen(ddl->category);
+           idRef = -1;
+           /*
+           ** Cross reference is only valid within the same stream.
+           */
+           if ((ddl->reference != NULL) && 
+               (ddl->streamId == ddl->reference->streamId )) { 
+               /*
+               ** compute the rerefence token. This is the sequential 
+               ** number of the reference Ntuple for this stream.
+               */
+               for (i=0, idRef=0; i<NumOfNTuples; i++) { 
+                   if (NTuDDLList[i]->streamId == ddl->reference->streamId)
+                       idRef++;
+                   if (NTuDDLList[i]->id == ddl->reference->id) break;
+               }    
+          }
+    }      
+    if (xdr_int(xdrs, &nc_title) == FALSE) return FALSE;
+    if (xdr_int(xdrs, &nc_category) == FALSE) return FALSE;
+    if (xdr_int(xdrs, &idRef) == FALSE) return FALSE;
+    if (xdrs->x_op == XDR_DECODE) {
+       ddl->title = (char *) malloc(sizeof(char) * (nc_title +1));
+       ddl->category = (char *) malloc(sizeof(char) * (nc_category +1));
+       ddl->dbinFileName = NULL;
+       ddl->streamId = -1;
+    }   
+    if (xdr_int(xdrs,&(ddl->uid)) == FALSE) return FALSE;
+    if (xdr_string(xdrs, &(ddl->title), nc_title) == FALSE) return FALSE;
+    if (xdr_string(xdrs, &(ddl->category), 
+                      nc_category) == FALSE) return FALSE;
+    if (idRef == -1) {                  
+        if (xdrs->x_op == XDR_DECODE) 
+           ddl->descrNtu = (descrGenNtuple *) malloc (sizeof(descrGenNtuple));
+         if (ddl->descrNtu == NULL) dNTu = ddl->reference->descrNtu;
+           else dNTu = ddl->descrNtu; 
+        if (xdr_mcfast_descrNTU(xdrs, version, dNTu) == FALSE) 
+            return FALSE;
+        if (xdrs->x_op == XDR_DECODE) ddl->reference = NULL; 
+    } else {
+        if (xdrs->x_op == XDR_DECODE) {
+              ddl->descrNtu = NULL;
+              ddl->referenceId = idRef;
+              /* we will set the reference pointer in mcfio_Direct */
+        }
+    }        
+    return TRUE; 
+    	      
+}
+
+static bool_t xdr_mcfast_descrNTU(XDR *xdrs, char *version,
+                                    descrGenNtuple *dNTu)
+{
+    int i, nc_desc, nc_title;
+    u_int nn;
+    char *tc;
+    /*
+    ** This is the first version, let us not get too compilcated..
+    */
+    
+    if (xdr_int(xdrs,&(dNTu->numVariables)) == FALSE) return FALSE;
+    dNTu->numAvailable = dNTu->numVariables;
+    if (xdr_int(xdrs,&(dNTu->maxMultiplicity)) == FALSE) return FALSE;
+    if (xdr_int(xdrs,&(dNTu->orgStyle)) == FALSE)return FALSE;
+    if (xdr_int(xdrs,&(dNTu->firstIndexed)) == FALSE) return FALSE;
+    if (xdrs->x_op == XDR_ENCODE)  nc_title = strlen(dNTu->title);
+    if (xdr_int(xdrs, &nc_title) == FALSE) return FALSE;
+    if (xdrs->x_op == XDR_ENCODE)  nc_desc = strlen(dNTu->description);
+    if (xdr_int(xdrs, &nc_desc) == FALSE) return FALSE;
+    if (xdrs->x_op == XDR_DECODE) {
+        dNTu->title = (char *) malloc(sizeof(char) * (nc_title+1));
+        dNTu->subXDROffset = NULL;
+        dNTu->description = (char *) malloc(sizeof(char) * (nc_desc+1));
+        dNTu->varOrdering = (int *) malloc(sizeof(int) * dNTu->numVariables);
+        for (i=0; i<dNTu->numVariables; i++) dNTu->varOrdering[i] = i;
+        if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
+           dNTu->subXDROffset = NULL;
+           dNTu->subOffset = NULL;  
+        } else {
+           dNTu->subOffset = 
+          (long *) malloc(sizeof(long) * dNTu->maxMultiplicity);
+           dNTu->subXDROffset = 
+          (u_int *) malloc(sizeof(long) * dNTu->maxMultiplicity);
+        }  
+        dNTu->variables =
+        (varGenNtuple **) malloc(sizeof(varGenNtuple *) * dNTu->numVariables);  
+        for (i=0; i<dNTu->numVariables; i++)
+            dNTu->variables[i] = (varGenNtuple *) malloc(sizeof(varGenNtuple));
+     }
+     tc = dNTu->nameIndex;
+     if (xdr_string(xdrs, &tc, 31) == FALSE) return FALSE;
+     if (xdr_string(xdrs, 
+        (char **) &(dNTu->title), nc_title) == FALSE) return FALSE;
+     if (xdr_string(xdrs,
+           &(dNTu->description), nc_desc) == FALSE) return FALSE;
+     tc =  dNTu->version;     
+     if (xdr_string(xdrs,  &tc, 7) == FALSE) return FALSE;
+     if (xdr_long(xdrs,  &(dNTu->multOffset)) == FALSE) return FALSE;
+     if (xdr_long(xdrs,  &(dNTu->fenceOffset)) == FALSE) return FALSE;
+     nn = dNTu->maxMultiplicity;
+     if (dNTu->orgStyle != PARALLEL_ARRAY_NTU) { 
+        if (xdr_array(xdrs, 
+      (char **) &(dNTu->subOffset), &nn, nn, sizeof(long), (void *) xdr_long) == FALSE) 
+           return FALSE;
+     }      
+     for (i=0; i<dNTu->numVariables; i++) 
+	if (xdr_mcfast_varDescrNTU(xdrs, version, dNTu->variables[i]) == FALSE)
+	        return FALSE;
+     return TRUE;
+}
+static bool_t xdr_mcfast_varDescrNTU(XDR *xdrs, char *version,
+                                    varGenNtuple *var)
+{
+    int nc_name, nc_desc, *pdim;
+    u_int nn;
+    
+    
+    
+    if (xdrs->x_op == XDR_ENCODE)  nc_name = strlen(var->name);
+    if (xdr_int(xdrs, &nc_name) == FALSE) return FALSE;
+    if (xdrs->x_op == XDR_ENCODE) {
+         if (var->description == NULL) nc_desc = 0;
+             else nc_desc = strlen(var->description);
+    }     
+    if (xdr_int(xdrs, &nc_desc) == FALSE) return FALSE;
+    if (xdrs->x_op == XDR_DECODE) {
+        var->name = (char *) malloc(sizeof(char) * (nc_name+1));
+        if (nc_desc>0) 
+           var->description = (char *) malloc(sizeof(char) * (nc_desc+1));
+        else    var->description = NULL;
+        var->nameBlank = FALSE;
+     }
+  
+     if (xdr_string(xdrs, &(var->name), nc_name) == FALSE) return FALSE;
+     if (nc_desc > 0) 
+        if (xdr_string(xdrs, &(var->description), nc_desc) == FALSE) 
+             return FALSE;
+     if (xdr_int(xdrs,&(var->type)) == FALSE) return FALSE;
+     if (xdr_char(xdrs,&(var->isFixedSize)) == FALSE) return FALSE;
+     if (xdr_int(xdrs,&(var->numDim)) == FALSE) return FALSE;
+     nn = var->numDim;
+     pdim = var->dimensions;
+     if ((nn > 0) && (xdr_array(xdrs, 
+        (char **) &pdim, &nn, nn, sizeof(int), (void *) xdr_int)) == FALSE) 
+           return FALSE;
+     if (xdrs->x_op == XDR_ENCODE) nn = (u_int) var->lengthB;  
+     if (xdr_u_int(xdrs,&(nn)) == FALSE) return FALSE;
+     if (xdrs->x_op == XDR_DECODE) var->lengthB = (size_t) nn;
+     if (xdrs->x_op == XDR_ENCODE) nn = (u_int) var->lengthW;  
+     if (xdr_u_int(xdrs,&(nn)) == FALSE) return FALSE;
+     if (xdrs->x_op == XDR_DECODE) var->lengthW = (size_t) nn;  
+     if (xdr_long(xdrs,&(var->offset)) == FALSE) return FALSE;
+     return TRUE;
+}
+/*
+** Generalized NTuple XDR filter
+*/
+bool_t xdr_mcfast_NTuple(XDR *xdrs, descrGenNtuple *dNTu,
+ 		 int *pnTot, int nTupleId, char* version)
+{
+    int i, j, id, nm, lastFixed;
+    u_int nn;
+    char *vv, *cDat, *start;
+    int *pnMult;
+    void *pnFence;
+    int *ipnFence;
+    void *pt;
+    bool_t ok;
+/*
+** Upon write, check that the version token is identical to the one stored 
+** in the ddl. 
+*/
+     start = version;
+     if(dNTu->firstIndexed == -1) lastFixed = dNTu->numVariables;
+        else lastFixed = dNTu->firstIndexed;
+     if ((xdrs->x_op == XDR_ENCODE) || (xdrs->x_op == XDR_MCFIOCODE)) {
+         nn = strlen(dNTu->version);
+         if (strncmp(version, dNTu->version, (size_t) nn ) != 0) {
+              fprintf (stderr, "mcfio_NTuple: version mismatch! \n\
+          Version used in the Event loop = %s\n\
+                  ...  in the DDl template = %s\n", version,dNTu->version);
+              return FALSE;
+         }
+         id = nTupleId;
+/*
+**   Compute the total length 
+*/
+         cDat = start; cDat +=  dNTu->multOffset;
+         pnMult = (int *) cDat;
+         nm = *pnMult;
+         for (i=0, nn=0; i<lastFixed; i++)
+               nn += dNTu->variables[i]->lengthB;
+         if(dNTu->firstIndexed != -1) 
+             for(i=dNTu->firstIndexed; i<dNTu->numVariables; i++) 
+                nn += (dNTu->variables[i]->lengthB * nm);
+         *pnTot = 6 + nn/4;      
+     }
+     if (xdr_int(xdrs, &id) == FALSE) return FALSE;
+     if (xdr_int(xdrs, pnTot) == FALSE) return FALSE;
+     if (xdrs->x_op == XDR_ENCODE) {
+         vv = dNTu->version;
+         if (xdr_string(xdrs, &vv, 11) == FALSE) return FALSE;
+     } else  if (xdrs->x_op == XDR_DECODE) {
+         if (xdr_string(xdrs, &version, 11) == FALSE) return FALSE;
+         if (strcmp(version, dNTu->version) != 0) {
+              fprintf (stderr, "mcfio_NTuple: version mismatch! \n\
+          Version used in the Event loop = %s\n\
+                  ...  in the DDl template = %s\n", version,dNTu->version);
+              return FALSE;
+         }
+         if (id != nTupleId) {
+              fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected NTuple identifier %d instead of %d\n", id, nTupleId);
+          return FALSE;
+          }
+     }
+         
+     cDat = start; cDat +=  dNTu->multOffset;
+     pnMult = (int *) cDat;
+     if (xdr_int(xdrs, pnMult) == FALSE) return FALSE;
+     /*
+     ** Close the fence now, we will check it upon DECODE at the end
+     */
+     cDat = start; cDat +=  dNTu->fenceOffset;
+     pnFence = (void *) cDat;
+     if (xdrs->x_op == XDR_ENCODE) memcpy(pnFence, pnTot, sizeof(int));
+     if (xdr_int(xdrs, (int *) pnFence) == FALSE) return FALSE;
+     nm = *pnMult;
+     for (i=0; i<lastFixed; i++) {
+        if (dNTu->variables[i]->lengthW == 1) {
+           cDat = start; cDat += dNTu->variables[i]->offset;
+           pt = (void *) cDat;
+           switch (dNTu->variables[i]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      ok = xdr_char(xdrs, (char *) pt);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_short(xdrs, (short *) pt);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_int(xdrs, (int *) pt);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_float(xdrs, (float *) pt); 
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_double(xdrs, (double *) pt);
+                      break;
+                   case COMPLEX_NTU:
+                      nn =2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn =2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_long(xdrs, (long *) pt);
+                      break;
+                   default :
+                       fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected variables type %d on NTuple %d\n", 
+                       dNTu->variables[i]->type, nTupleId);
+                       break;
+              }
+        }      
+        else if (dNTu->variables[i]->lengthW > 0) {
+           cDat = start; cDat +=  dNTu->variables[i]->offset;
+           pt = (void *) cDat;
+           nn = dNTu->variables[i]->lengthW;
+           switch (dNTu->variables[i]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      ok = xdr_bytes(xdrs, (char **) &pt, &nn, nn);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(short), (void *) xdr_short);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(int), (void *) xdr_int);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(long), (void *) xdr_long);
+                      break;
+                   default :
+                       fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected variables type %d on NTuple %d\n", 
+                       dNTu->variables[i]->type, nTupleId);
+                       break;
+              }
+          if (ok == FALSE) return FALSE;    
+         }
+      }
+      if (dNTu->firstIndexed != -1) {
+         if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
+          for (i=dNTu->firstIndexed; i<dNTu->numVariables; i++) {
+                 cDat = start; cDat +=  dNTu->variables[i]->offset;
+                 pt = (void *) cDat;
+                 nn = nm * dNTu->variables[i]->lengthW;
+                 switch (dNTu->variables[i]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      vv = (char *) pt;
+                      ok = xdr_bytes(xdrs, (char **) &pt, &nn, nn);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(short), (void *) xdr_short);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(int), (void *) xdr_int);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(long), (void *) xdr_long);
+                      break;
+                   default :
+                       fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected variables type %d on NTuple %d\n", 
+                       dNTu->variables[i]->type, nTupleId);
+                       break;
+              }
+          if (ok == FALSE) return FALSE;    
+        }
+     } else { /*dump the substructures one a time */
+     for (j=0; j<nm; j++) {
+       for (i=dNTu->firstIndexed; i<dNTu->numVariables; i++) {
+        cDat = start; 
+        cDat += (dNTu->subOffset[j] + dNTu->variables[i]->offset);
+        pt = (void *) cDat;
+        if (dNTu->variables[i]->lengthW == 1) {
+           switch (dNTu->variables[i]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      ok = xdr_char(xdrs, (char *) pt);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_short(xdrs, (short *) pt);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_int(xdrs, (int *) pt);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_float(xdrs, (float *) pt); 
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_double(xdrs, (double *) pt);
+                      break;
+                   case COMPLEX_NTU:
+                      nn =2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn =2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_long(xdrs, (long *) pt);
+                      break;
+                   default :
+                       fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected variables type %d on NTuple %d\n", 
+                       dNTu->variables[i]->type, nTupleId);
+                       break;
+              }
+        }      
+        else if (dNTu->variables[i]->lengthW > 0) {
+           nn = dNTu->variables[i]->lengthW;
+           switch (dNTu->variables[i]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      ok = xdr_bytes(xdrs, (char **) &pt, &nn, nn);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(short), (void *) xdr_short);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(int), (void *) xdr_int);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(long), (void *) xdr_long);
+                      break;
+                   default :
+                       fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected variables type %d on NTuple %d\n", 
+                       dNTu->variables[i]->type, nTupleId);
+                       break;
+              }
+          if (ok == FALSE) return FALSE;    
+         }
+        } /*end of i loop */
+       } /*end of j loop */
+      } /* End of orgStyle clause */
+      } /* End of firstIndexed clause */
+      /*
+      ** Check the fence.. 
+      */
+      ipnFence = (int *) pnFence;
+      if ((xdrs->x_op == XDR_DECODE) && (*ipnFence != *pnTot)) {
+              fprintf (stderr, "mcfio_NTuple: Suspected Data Overwrite! \n\
+          Fence content found on the input stream is = %d\n\
+                  ...  while we expect %d\n", *ipnFence, *pnTot);
+              return FALSE;
+      }
+      return TRUE;
+}
+
+/*
+** Generalized NTuple XDR filter, for DECODE only, used exclusively 
+** to establish the relative XDR pointers.
+*/
+bool_t xdr_mcfast_NTupleXDRPtr(XDR *xdrs, descrGenNtuple *dNTu,
+ 		 int *pnTot, int nTupleId, char* version)
+{
+    int i, j, id, nm, lastFixed;
+    u_int nn, startXDR;
+    char *vv, *cDat;
+    int *pnMult, *pnFence;
+    void *start, *pt;
+    bool_t ok;
+    
+    /*
+    ** Allocate memory for supointer array if need be.
+    */
+     if(dNTu->firstIndexed == -1) lastFixed = dNTu->numVariables;
+        else lastFixed = dNTu->firstIndexed;
+        
+     if (dNTu->subXDROffset != NULL) free(dNTu->subXDROffset);
+     dNTu->subXDROffset = 
+          (u_int *) malloc (sizeof(u_int) * dNTu->maxMultiplicity);
+     start = (void *) version;
+     startXDR = xdr_getpos(xdrs);
+     if (xdr_int(xdrs, &id) == FALSE) return FALSE;
+      if (xdr_int(xdrs, pnTot) == FALSE) return FALSE;
+
+      if (xdr_string(xdrs, &version, 11) == FALSE) return FALSE;
+      if (id != nTupleId) {
+              fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected NTuple identifier %d instead of %d\n", id, nTupleId);
+          return FALSE;
+      }
+     cDat = start; cDat +=  dNTu->multOffset;
+     pnMult = (int *) cDat;
+     dNTu->multXDROffset = xdr_getpos(xdrs) - startXDR;
+     if (xdr_int(xdrs, pnMult) == FALSE) return FALSE;
+     /*
+     ** Close the fence now, we will check it upon DECODE at the end
+     */
+     cDat = start; cDat += dNTu->fenceOffset;
+     pnFence = (int *) cDat;
+     dNTu->fenceXDROffset = xdr_getpos(xdrs) - startXDR;
+     if (xdr_int(xdrs, (int *) pnFence) == FALSE) return FALSE;
+     nm = *pnMult;
+     for (i=0; i<lastFixed; i++) {
+        dNTu->variables[i]->offsetXDR = 0;
+        if (dNTu->variables[i]->lengthW == 1) {
+           cDat = start; cDat +=  dNTu->variables[i]->offset;
+           pt = (void *) cDat;
+          dNTu->variables[i]->offsetXDR = xdr_getpos(xdrs) - startXDR;
+           switch (dNTu->variables[i]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      ok = xdr_char(xdrs, (char *) pt);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_short(xdrs, (short *) pt);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_int(xdrs, (int *) pt);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_float(xdrs, (float *) pt); 
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_double(xdrs, (double *) pt);
+                      break;
+                   case COMPLEX_NTU:
+                      nn =2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn =2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_long(xdrs, (long *) pt);
+                      break;
+                   default :
+                       fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected variables type %d on NTuple %d\n", 
+                       dNTu->variables[i]->type, nTupleId);
+                       break;
+              }
+        }      
+        else if (dNTu->variables[i]->lengthW > 0) {
+           cDat = start;  cDat += dNTu->variables[i]->offset;
+           pt = (void *) cDat;
+           nn = dNTu->variables[i]->lengthW;
+           dNTu->variables[i]->offsetXDR = xdr_getpos(xdrs) - startXDR;
+           switch (dNTu->variables[i]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      ok = xdr_bytes(xdrs, (char **) &pt, &nn, nn);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(short), (void *) xdr_short);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(int), (void *) xdr_int);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(long), (void *) xdr_long);
+                      break;
+                   default :
+                       fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected variables type %d on NTuple %d\n", 
+                       dNTu->variables[i]->type, nTupleId);
+                       break;
+              }
+          if (ok == FALSE) return FALSE;    
+         }
+      }
+      if (dNTu->firstIndexed != -1) {
+      if (dNTu->orgStyle == PARALLEL_ARRAY_NTU) {
+          for (i=dNTu->firstIndexed; i<dNTu->numVariables; i++) {
+                 cDat =start;  cDat += dNTu->variables[i]->offset;
+                 pt = (void *) cDat;
+                 nn = nm * dNTu->variables[i]->lengthW;
+                 dNTu->variables[i]->offsetXDR = xdr_getpos(xdrs) - startXDR;
+                 switch (dNTu->variables[i]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      vv = (char *) pt;
+                      ok = xdr_bytes(xdrs, (char **) &pt, &nn, nn);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(short), (void *) xdr_short);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(int), (void *) xdr_int);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(long), (void *) xdr_long);
+                      break;
+                   default :
+                       fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected variables type %d on NTuple %d\n", 
+                       dNTu->variables[i]->type, nTupleId);
+                       break;
+              }
+          if (ok == FALSE) return FALSE;    
+        }
+     } else { /*dump the substructure one a time */
+     for (j=0; j<nm; j++) {
+       dNTu->subXDROffset[j] = xdr_getpos(xdrs) - startXDR;
+       for (i=dNTu->firstIndexed; i<dNTu->numVariables; i++) {
+        cDat = start; 
+        cDat += (dNTu->subOffset[j] + dNTu->variables[i]->offset);
+        pt = (void *) cDat;
+        if (j == 0) dNTu->variables[i]->offsetXDR = 0;
+        if (dNTu->variables[i]->lengthW == 1) {
+          if (j == 0)  dNTu->variables[i]->offsetXDR =
+                 xdr_getpos(xdrs) - startXDR- dNTu->subXDROffset[j];
+           switch (dNTu->variables[i]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      ok = xdr_char(xdrs, (char *) pt);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_short(xdrs, (short *) pt);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_int(xdrs, (int *) pt);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_float(xdrs, (float *) pt); 
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_double(xdrs, (double *) pt);
+                      break;
+                   case COMPLEX_NTU:
+                      nn =2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn =2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_long(xdrs, (long *) pt);
+                      break;
+                   default :
+                       fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected variables type %d on NTuple %d\n", 
+                       dNTu->variables[i]->type, nTupleId);
+                       break;
+              }
+        }      
+        else if (dNTu->variables[i]->lengthW > 0) {
+           nn = dNTu->variables[i]->lengthW;
+           if (j == 0) dNTu->variables[i]->offsetXDR =
+                 xdr_getpos(xdrs) - startXDR - dNTu->subXDROffset[0];
+           switch (dNTu->variables[i]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      ok = xdr_bytes(xdrs, (char **) &pt, &nn, nn);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(short), (void *) xdr_short);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(int), (void *) xdr_int);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_array(xdrs, 
+                         (char **) &pt, &nn, nn, sizeof(long), (void *) xdr_long);
+                      break;
+                   default :
+                       fprintf (stderr, "mcfio_NTuple: internal error! \n\
+          Unexpected variables type %d on NTuple %d\n", 
+                       dNTu->variables[i]->type, nTupleId);
+                       break;
+              }
+          if (ok == FALSE) return FALSE;    
+         }
+        } /*end of i loop */
+       } /*end of j loop */
+      } /* End of orgStyle clause */
+      } /* End of firstIndexed clause */
+      /*
+      ** Check the fence.. 
+      */
+      if (*pnFence != *pnTot) {
+              fprintf (stderr, "mcfio_NTuple: Suspected Data Overwrite! \n\
+          Fence content found on the input stream is = %d\n\
+                  ...  while we expect %d\n", *pnFence, *pnTot);
+              return FALSE;
+      }
+      return TRUE;
+}
+/*
+** Generalized NTuple XDR filter, used for Decode only. 
+** Simply decode the multiplicty value. No checks whatsoever!
+*/
+bool_t xdr_mcfast_NTupleMult(mcfStream *str, descrGenNtuple *dNTu,
+ 		char* version)
+{
+    char *cDat;
+    
+     cDat = version;
+     cDat +=  dNTu->multOffset;     
+     xdr_setpos(str->xdr, (str->currentPos + dNTu->multXDROffset) );
+     return  (xdr_int(str->xdr, ((int *) cDat)));
+}
+
+/*
+** Generalized NTuple XDR filter, used for Decode only. 
+** Simply decode one variable (scalar) or array value. No checks whatsoever!
+** Not applicable if the structure organization style is VAX FORTRAN d/s 
+** and the index corresponds to an indexed variable.
+*/
+bool_t xdr_mcfast_NTupleVar(mcfStream *str, descrGenNtuple *dNTu,
+ 		int ivar, char* version)
+{
+    char *cDat;
+    u_int nn;
+    void *pt;
+    int ivarP;
+    
+     ivarP = ivar;
+     while (dNTu->variables[ivarP]->lengthW == 0) ivarP--;
+     cDat = version;
+     cDat += dNTu->variables[ivarP]->offset;
+     pt = (void *) cDat;     
+     xdr_setpos(str->xdr, 
+              (str->currentPos + dNTu->variables[ivarP]->offsetXDR));
+     if ((dNTu->variables[ivarP]->lengthW == 1) &&
+         (ivarP < dNTu->firstIndexed)) {
+          switch (dNTu->variables[ivarP]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      return  xdr_char(str->xdr, (char *) pt);
+                   case INTEGER2_NTU:
+                      return  xdr_short(str->xdr, (short *) pt);
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      return  xdr_int(str->xdr, (int *) pt);
+                   case REAL_NTU:
+                      return  xdr_float(str->xdr, (float *) pt); 
+                   case DBL_PRECISION_NTU:
+                      return  xdr_double(str->xdr, (double *) pt);
+                   case COMPLEX_NTU:
+                      nn =2;
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                   case DBL_COMPLEX_NTU:
+                      nn =2;
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                   case POINTER_NTU:
+                      return  xdr_long(str->xdr, (long *) pt);
+                   default :
+                      return FALSE;
+              }
+        } else {
+           nn = dNTu->variables[ivarP]->lengthW;
+           switch (dNTu->variables[ivarP]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      return  xdr_bytes(str->xdr, (char **) &pt, &nn, nn);
+                   case INTEGER2_NTU:
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(short), (void *) xdr_short);
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(int), (void *) xdr_int);
+                   case REAL_NTU:
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                   case DBL_PRECISION_NTU:
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                   case COMPLEX_NTU:
+                      nn = nn*2;
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                   case DBL_COMPLEX_NTU:
+                      nn = nn*2;
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                   case POINTER_NTU:
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(long), (void *) xdr_long);
+                   default :
+                       return FALSE;
+              }
+         }
+}
+/*
+** Generalized NTuple XDR filter, used for Decode only. 
+** Simply decode one variable (scalar) or array value. No checks whatsoever!
+** Not applicable if the structure organization style is parallel array
+** or the index corresponds to a fixed size variable.
+*/
+bool_t xdr_mcfast_NTupleSubVar(mcfStream *str, descrGenNtuple *dNTu,
+ 		int ivar, int multIndex, char* version)
+{
+    char *cDat;
+    u_int nn;
+    void *pt;
+    int ivarP;
+    
+     ivarP = ivar;
+     while (dNTu->variables[ivarP]->lengthW == 0) ivarP--;
+     cDat = version;
+     cDat += dNTu->subOffset[multIndex];
+     cDat += dNTu->variables[ivarP]->offset;
+     pt = (void *) cDat;     
+     xdr_setpos(str->xdr, 
+              (str->currentPos +  dNTu->subXDROffset[multIndex] +
+              dNTu->variables[ivarP]->offsetXDR));
+     if (dNTu->variables[ivarP]->lengthW == 1) { 
+          switch (dNTu->variables[ivarP]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      return  xdr_char(str->xdr, (char *) pt);
+                   case INTEGER2_NTU:
+                      return  xdr_short(str->xdr, (short *) pt);
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      return  xdr_int(str->xdr, (int *) pt);
+                   case REAL_NTU:
+                      return  xdr_float(str->xdr, (float *) pt); 
+                   case DBL_PRECISION_NTU:
+                      return  xdr_double(str->xdr, (double *) pt);
+                   case COMPLEX_NTU:
+                      nn =2;
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                   case DBL_COMPLEX_NTU:
+                      nn =2;
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                   case POINTER_NTU:
+                      return  xdr_long(str->xdr, (long *) pt);
+                   default :
+                      return FALSE;
+              }
+        } else {
+           nn = dNTu->variables[ivarP]->lengthW;
+           switch (dNTu->variables[ivarP]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      return  xdr_bytes(str->xdr, (char **) &pt, &nn, nn);
+                   case INTEGER2_NTU:
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(short), (void *) xdr_short);
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(int), (void *) xdr_int);
+                   case REAL_NTU:
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                   case DBL_PRECISION_NTU:
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                   case COMPLEX_NTU:
+                      nn = nn*2;
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                   case DBL_COMPLEX_NTU:
+                      nn = nn*2;
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                   case POINTER_NTU:
+                      return  xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(long), (void *) xdr_long);
+                   default :
+                       return FALSE;
+              }
+         }
+}
+/*
+** Generalized NTuple XDR filter, used for Decode only. 
+** Simply decode a sub-structure given a value for the multiplicity index.
+** Not applicable if the structure organization style is parallel array.
+** No check whatsover!
+*/
+bool_t xdr_mcfast_NTupleSubStruct(mcfStream *str, descrGenNtuple *dNTu,
+ 		int multIndex, char* version)
+{
+    char *cDat;
+    u_int nn;
+    void *pt;
+    int iv;
+    bool_t ok;
+    
+     xdr_setpos(str->xdr, 
+              (str->currentPos +  dNTu->subXDROffset[multIndex]));
+     for (iv=dNTu->firstIndexed; iv<dNTu->numVariables; iv++) {          
+        cDat = version;
+        cDat += 
+             dNTu->subOffset[multIndex] + dNTu->variables[iv]->offset;
+        pt = (void *) cDat;
+        if (dNTu->variables[iv]->lengthW == 1) {
+              switch (dNTu->variables[iv]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      ok =  xdr_char(str->xdr, (char *) pt);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_short(str->xdr, (short *) pt);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_int(str->xdr, (int *) pt);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_float(str->xdr, (float *) pt); 
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_double(str->xdr, (double *) pt);
+                      break;
+                   case COMPLEX_NTU:
+                      nn =2;
+                      ok = xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn =2;
+                      ok = xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_long(str->xdr, (long *) pt);
+                   default :
+                      return FALSE;
+              }
+        } else if (dNTu->variables[iv]->lengthW > 1){
+           nn = dNTu->variables[iv]->lengthW;
+           switch (dNTu->variables[iv]->type) {
+                   case BYTE_NTU: case CHARACTER_NTU:
+                      ok = xdr_bytes(str->xdr, (char **) &pt, &nn, nn);
+                      break;
+                   case INTEGER2_NTU:
+                      ok = xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(short), (void *) xdr_short);
+                      break;
+                   case LOGICAL_NTU: case INTEGER_NTU:
+                      ok = xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(int), (void *) xdr_int);
+                      break;
+                   case REAL_NTU:
+                      ok = xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_PRECISION_NTU:
+                      ok = xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(float), (void *) xdr_float);
+                      break;
+                   case DBL_COMPLEX_NTU:
+                      nn = nn*2;
+                      ok = xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(double), (void *) xdr_double);
+                      break;
+                   case POINTER_NTU:
+                      ok = xdr_array(str->xdr, 
+                         (char **) &pt, &nn, nn, sizeof(long), (void *) xdr_long);
+                      break;
+                   default :
+                       return FALSE;
+              }
+           }
+       }
+       return TRUE;
+}
Index: /trunk/Utilities/mcfio/mcf_nTupleDescript.h
===================================================================
--- /trunk/Utilities/mcfio/mcf_nTupleDescript.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_nTupleDescript.h	(revision 3)
@@ -0,0 +1,86 @@
+/*******************************************************************************
+*									       *
+* mcf_nTupleDescript.h -- Include file for mcfast generalized nTuple           *
+*    descriptors.  This is a genric structres that can hold info about	       *
+*    specficic instances of a generalized nTuple. 			       *
+*									       *
+*	P. Lebrun, September 1995.					       *
+*									       *
+*******************************************************************************/
+/*
+** Information concerning a generic variable within an Ntuple
+*/
+enum varTypes {BYTE_NTU, CHARACTER_NTU, INTEGER2_NTU, LOGICAL_NTU,
+               INTEGER_NTU, REAL_NTU,
+               DBL_PRECISION_NTU, COMPLEX_NTU, DBL_COMPLEX_NTU, POINTER_NTU};
+
+enum orgStyles {PARALLEL_ARRAY_NTU, DATA_STRUCT_NTU};               
+               
+#define N_VAR_TYPES 10
+#define MAX_VAR_NAME  31
+#define MAX_NTU_TITLE 80
+#define MAX_VAR_DESCRIP 1023
+#define MAX_VAR_DIMENSIONS 4
+#define NUM_START_VARIABLES 10
+#define NTU_MAX_TITLE_LENGTH 80
+#define NTU_MAX_CATEGORY_LENGTH 255
+#define NTU_MAX_CATEGORY_DEPTH 40
+#define NTU_START_LIST_SIZE 20
+
+typedef struct {
+    char nameBlank;   /* flag indicating that the variable does not exist. */
+    char *name;       /* Mnemonic name of the variable. */
+    char *description;/* description for the variable */
+    int  type;        /* Variable type (int, ...) see above enum varTypes */
+    char isFixedSize; /* Variable is or is not indexed by nTuple multiplicity*/
+    int  numDim;      /* The variable dimensions, not counting mult. one */
+    int  dimensions[MAX_VAR_DIMENSIONS+1];
+                      /* Variable dims, not counting the multiplicity one*/
+    size_t lengthW;   /* Used in XDR filtering, length in words */
+    size_t lengthB; /* Used in XDR filtering, length in byte */                
+    long offset;    /* The variable virtual address for a given instance */
+    u_int offsetXDR; /* The variable relative address within the struct. */
+} varGenNtuple;
+
+typedef struct {
+    int numVariables;    /* The total number of variables in the structure */
+    int numAvailable;    /* The number of available var. in var. array  */
+    char nameIndex[32];  /* The name for the Ntuple single index */
+    int maxMultiplicity; /* The maximum multiplicity for any instances  */
+    char *title;	 /* Title for the structure */
+    char *description;   /* Description of this structure. */
+    char version[8];	 /* The version string */
+    int orgStyle;	 /* The organization of the indexed variables */
+    void *address;	 /* Virtual address of a particular instance */
+    long multOffset;      /* Offset for the multiplicity offset */
+    u_int multXDROffset;   /* Adress for the multiplicity offset */
+    long fenceOffset;     /* Offset for the fence */
+    u_int fenceXDROffset;  /* XDR offset for the fence */
+    long  *subOffset;     /* Offset for the sub structures */
+    u_int  *subXDROffset;  /* XDR offset for the sub structures */
+    varGenNtuple **variables; /* The variable descriptions */
+    int *varOrdering;    /* Ordering of the variables for the dbin, .h..  file*/
+    int firstIndexed;    /* Once ordered, the first indexed for indexed part */
+} descrGenNtuple; 
+
+/*
+** A Data structure to hold a DDL, without MOTIF widget, to be used in 
+** stand alone mode in mcfio.
+*/
+
+typedef struct nTuDDLRec {
+    int id;             /* The id of the NTuple, as returned to the user */
+    int seqNTuId;	/* The sequential number for this particular stream */
+    int uid;            /* The user Id, Unique (within a Category) id */    
+    char *category;
+    char *title;
+    char *dbinFileName; /* dbin filename, not guarantted to be there. */
+    int streamId;       /* The stream on which this ddl is assigned to */
+    int referenceId;     
+    struct nTuDDLRec *reference;
+                       /* the reference in case a similar ddl has already 
+    			   been installed in the running image. */
+    			   
+    descrGenNtuple *descrNtu; /* The Ntuple Descriptor */
+} nTuDDL;    
+
Index: /trunk/Utilities/mcfio/mcf_ntuBldDbinc.c
===================================================================
--- /trunk/Utilities/mcfio/mcf_ntuBldDbinc.c	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_ntuBldDbinc.c	(revision 3)
@@ -0,0 +1,526 @@
+/*
+ *     dbin.cc
+ *
+ *  C++ utility routines for the dbin package: see dbin.lex
+ *
+ *  N.B. The Strings class from the CLHEP library is used.
+ *
+ *       Torre Wenaus 04/01/1994
+ *
+ * Modifications:
+ * 8/21/95   T. Wenaus Mod history started
+ * 8/21/95   TW        Strings class removed from dbin generated code.
+ * 8/22/95   TW        Strings class removed from dbinc.cc
+ *
+ * November 1995: some clean up to be able to run this code and 
+ * standard dbin simulateneously..
+ * Make some routine & variable static, and change the name of routine 
+ * called from the outside, following the Nirvana/mcfio conventions.
+ * 
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <limits.h>
+#include "mcf_ntuBldDbinc.h"
+#include "mcf_ntubld_db.h"
+
+static void dbin_debug();
+static void lineparse();
+static void dbinparse(char* str, char* typ, char* nam, 
+                      char* var, char* com, char* dim);
+static void  getmembers(long nmems);
+static void getvalues();
+static char* stlower(char*);
+static void chrcat(char* str, char chr);
+static char* token(char** str, char* sep);
+static int testsep(char chr, char *sep);
+static void mcf_ntubld_interpret();
+
+static char varname[40], objname[40], curstruct[40];
+static char chvalues[500], *values, dim[20];
+static char tok1[30], tok2[30], tok3[100], com[100];
+static char line[1000];
+static int n_instance_line_title, n_instance_header, n_instance_variable;
+
+static double dvar[100];
+static float rvar[100];
+static char chvar[100][80];
+static char dbpath[FILENAME_MAX+1], filename[FILENAME_MAX+1];
+static long nvars, morevalues, n_templates;
+static long inc_depth, n_instance, debug_on;
+static int isl;
+static long n_significant, lnlen=0; 
+static FILE *inFile, *curFile1,  *curFile2,  *curFile3,  *curFile4,  *curFile5;
+static const char *fnamep;
+static void dbin_getrec(char* fname[],void (*)(void));
+
+static void dbin_getrec(char* fname[],void (*interpret)(void))
+{
+  char chr;
+  int istat;
+  long inc_depth_old = 0;
+  /*
+  ** Start be intializing all these globals, to be able to call this routine
+  ** more than once.. 
+  */
+  inc_depth = 0;
+  n_instance = 0;
+  lnlen = 0; 
+  /* extract path from filename */
+  strcpy(filename,*fname);
+  if (strrchr(filename,'/') != NULL)  {
+      strcpy(dbpath,filename);
+      *(strrchr(dbpath,'/')+1)='\0';
+  } else {
+      dbpath[0] = '\0';
+  }
+
+  /* open file */
+  inFile = fopen(*fname,"r");
+  if (inFile == NULL) {
+    fprintf(stdout,"Error opening %s\n",*fname);
+    return;
+  }
+  else
+      {
+          if (debug_on) fprintf(stdout,"Opened %s\n",*fname);
+      }
+  /*  read a line */
+  while (inc_depth>=0) {
+    istat=1;
+    while (istat!=EOF) {
+        if (inc_depth > inc_depth_old) /*  need to open new file */
+        {
+          long ifstat;
+          ifstat=1;
+          fnamep = (const char *)filename;
+          if (inc_depth==1) {curFile1 = fopen(fnamep,"r");
+            if (curFile1==NULL) {
+              fprintf(stdout,"Error opening %s\n",fnamep);
+              ifstat=0;
+            }
+            else {
+                if (debug_on) fprintf(stdout,"Opened %s\n",fnamep);
+            }
+          }
+          if (inc_depth==2) {curFile2 = fopen(fnamep,"r");
+            if (curFile2==NULL) {
+              fprintf(stdout,"Error opening %s\n",fnamep);
+              ifstat=0;
+            }
+            else {
+                if (debug_on) fprintf(stdout,"Opened %s\n",fnamep);
+            }
+          }
+          if (inc_depth==3) {curFile3 = fopen(fnamep,"r");
+            if (curFile3==NULL) {
+              fprintf(stdout,"Error opening %s\n",fnamep);
+              ifstat=0;
+            }
+            else {
+                if (debug_on) fprintf(stdout,"Opened %s\n",fnamep);
+            }
+          }
+          if (inc_depth==4) {curFile4 = fopen(fnamep,"r");
+            if (curFile4==NULL) {
+              fprintf(stdout,"Error opening %s\n",fnamep);
+              ifstat=0;
+            }
+            else {
+                if (debug_on) fprintf(stdout,"Opened %s\n",fnamep);
+            }
+          }
+          if (inc_depth==5) {curFile5 = fopen(fnamep,"r");
+            if (curFile5==NULL) {
+              fprintf(stdout,"Error opening %s\n",fnamep);
+              ifstat=0;
+            }
+            else {
+                if (debug_on) fprintf(stdout,"Opened %s\n",fnamep);
+            }
+          }
+        }
+      inc_depth_old = inc_depth;
+      if (inc_depth==0) istat=fgetc(inFile);
+      if (inc_depth==1) istat=fgetc(curFile1);
+      if (inc_depth==2) istat=fgetc(curFile2);
+      if (inc_depth==3) istat=fgetc(curFile3);
+      if (inc_depth==4) istat=fgetc(curFile4);
+      if (inc_depth==5) istat=fgetc(curFile5);
+      chr = istat;
+        if (chr == '\t') chr = ' '; /*  remove tabs */
+        if (chr == '\n') { /* line is complete; process it */
+            if (morevalues == 1) {  /* line extension containing values */
+                /* if final significant char is '/', mark next
+                   line as values continuation */
+                int i;
+                isl=0;
+                for (i=0;i<strlen(line);i++) {
+                    if (line[i] == '!') i=strlen(line);
+                    if (line[i] == '/') isl=i;
+                }
+                if (isl != 0) {
+                    n_significant = 0;
+                    for (i=isl;i<strlen(line);i++) {
+                        if (line[i] == '!') i=strlen(line);
+                        if (line[i]!='/' && line[i]!=' ' && line[i]!='\t'
+                            && i < strlen(line) ) n_significant++;
+                    }
+                    if (n_significant != 0) morevalues = 0;
+                } else {
+                    morevalues = 0;
+                }
+                strcat(values," "); 
+                if (morevalues == 0) {
+                    strcat(values,line);
+                } else {
+                    strncat(values,line,isl-1);
+                }
+            } else { /* line is not an extension. Parse it. */
+                dbinparse(line, tok1, tok2, tok3, com, dim);
+            }
+            if (morevalues == 0) { 
+                /* no more line extensions to read. Process line. */
+                /* now interpret the line */
+                if (tok1[0] != '\0') {
+                    if (debug_on) fprintf(stdout,"%s %s %s\n",tok1,tok2,values);
+                    lineparse();
+                    (*interpret)();
+                }
+            }
+            line[0] = '\0';
+            lnlen = 0;
+        } else {
+            /* add to line */
+            if (chr != '\r') { line[lnlen++]=chr; line[lnlen]='\0'; }
+        }
+    }
+    inc_depth--; line[0] = '\0';
+  }
+  return;
+}
+
+/****************************************************************************/
+static void lineparse()
+{
+  char* tokn, *env, *envName, *tmp1, *tmp2;
+  long l, in_template;
+  varname[0] = '\0';
+  objname[0] = '\0';
+  if (!strcmp(tok1,"end")) {strcpy(curstruct,"--"); in_template = 0;}
+  if (!strcmp(tok1,"structure")) {strcpy(curstruct,tok2);}
+  if (!strcmp(tok1,"database")) ;
+  if (!strcmp(tok1,"incname")) ;
+  if (!strcmp(tok1,"index")) ;
+  if (!strcmp(tok1,"provide")) ;
+  if (!strcmp(tok1,"parent")) ;
+  if (!strcmp(tok1,"child")) ;
+  if (!strcmp(tok1,"dimension")) ;
+  if (!strcmp(tok1,"template")) {in_template = 1; strcpy(curstruct,tok2);
+    n_instance = 0;}
+  if (!strcmp(tok1,"command")) {in_template = 1; strcpy(curstruct,tok2);}
+  if (!strcmp(tok1,"include")) {  /* switch input to specified file */
+ /*
+ ** Commented out, we use absolute path name in the includes. 
+ ** This allows us to go to more than one directory..
+ */
+/*    strcpy(filename,dbpath); */ 
+/*    strcat(filename,tok2); */
+/*
+** We now implement translation of environmental variable
+**
+*/
+      if (tok2[0] == '$') {
+         tmp1 = strchr(&tok2[1], '/');
+         if (tmp1 == NULL) {
+              fprintf(stderr, "DBin error, Unkonw path %s\n", tok2);
+              return;
+         }
+         envName = (char *) malloc(sizeof(char) * (strlen(tok2)+1));
+         strcpy(envName, &tok2[1]);
+         tmp2 = strchr(envName, '/'); *tmp2 = '\0';
+         env = getenv(envName);
+         free(envName);
+         
+         if (env == NULL) { 
+              fprintf(stderr, "DBin error, Unkonw path %s\n", tok2);
+              return;
+         }
+         strcpy(filename,env); l = strlen(env); filename[l] = '/'; l++;
+         strcpy(&filename[l], tmp1);
+            
+      } else  strcpy(filename, tok2);
+    inc_depth++;
+  } 
+  if (!strcmp(tok1,"make")) {
+    n_instance++;
+    strcpy(varname,"TEMPLATE_");
+    strcat(varname,stlower(tok2));
+  }
+  if (!strcmp(tok1,"define")) {
+      /* get first token (name) from values list */
+    tokn = token(&values," \t");
+    strcpy(varname,"TEMPLATE_");
+    strcat(varname,tok2);
+    strcpy(objname,tok2);
+    strcat(objname,"_");
+    strcat(objname,tokn);
+  }
+  if (!strcmp(tok1,"call")) {
+      /* get first token (name) from values list */
+    tokn = token(&values," \t");
+    strcpy(varname,"COMMAND_");
+    strcat(varname,tok2);
+  }
+  if (!strncmp(tok1,"int",3) || !strcmp(tok1,"real") || !strcmp(tok1,"double") ||
+      !strncmp(tok1,"char",4) || !strcmp(tok1,"material") ) {
+    if ((! strncmp(curstruct,"--",2)) && (in_template == 0)) {
+      fprintf(stdout,"dbin: Parameter \"%s\" not in structure; ignored:\n",
+              tok2);
+      fprintf(stdout,"      %s\n",line);
+    } else {
+        /* parse values */
+      strcpy(varname,curstruct);
+      strcat(varname,".");
+      strcat(varname,tok2);
+      getvalues();
+    }
+  }
+}
+
+/****************************************************************************/
+static void dbinparse(char* str, char* typ, 
+                      char* nam, char* var, char* com, char* dim)
+{
+/* Parse from line the type, name, value, comment */
+  int i;
+  long nc = 0;
+
+  nvars = 1;
+  chvalues[0] = dim[0] = typ[0] = nam[0] = var[0] = com[0] = '\0';
+  values = chvalues;
+  
+/* if final significant char is '/', mark next line as values continuation */
+  isl=strlen(str);
+  for (i=0;i<strlen(str);i++) {
+      if (str[i] == '!') i=strlen(str);
+      if (str[i] == '/') isl=i;
+  }
+  morevalues = 0;
+  if (isl != strlen(str)) {
+      n_significant = 0;
+      for (i=isl;i<strlen(str);i++) {
+          if (str[i] == '!') i=strlen(str);
+          if (str[i]!='/' && str[i]!=' ' && str[i]!='\t'
+               && i < strlen(line) ) n_significant++;
+      }
+      if (n_significant == 0) morevalues = 1;
+  }
+
+    /* initial whitespace, type, whitespace */
+  while ((str[nc] == ' ') || (str[nc] == '\t')) ++nc;
+  while ((str[nc] != ' ') && (str[nc] != '\t')
+         && (nc < strlen(str))) chrcat(typ,str[nc++]);
+  while ((str[nc] == ' ') || (str[nc] == '\t')) ++nc;
+    /* name, whitespace, dimension? */
+  while ((str[nc] != ' ') && (str[nc] != '\t') && (str[nc] != '(' )
+         && (nc < strlen(str))) chrcat(nam,str[nc++]);
+  while ((str[nc] == ' ') || (str[nc] == '\t')
+         && (nc < strlen(str))) ++nc;
+  if (str[nc] == '(') {  /* have a dimensioned array */
+      /* get dimension */
+    while (str[++nc] != ')') chrcat(dim,str[nc]); nc++;
+    nvars = atol(dim);
+  }
+    /* skip over value(s) to comment */
+  while (  (str[nc] != '!')   && 
+           (str[nc] != '/' || ( morevalues && (nc != isl) ) )   &&
+           ( (nc < strlen(str)) || ( morevalues && (nc < isl)) )   ) chrcat(chvalues,str[nc++]);
+    /* comment */
+  while (((str[nc] == '!') || (str[nc] == '\t'))
+         && (nc < strlen(str))) ++nc;
+  while (nc <= strlen(str)) { chrcat(com,str[nc++]); }
+    /* turn mnemonic num into variable name var */
+  var = nam;
+}
+
+/****************************************************************************/
+
+static void getvalues()
+{
+    char* tokn;
+    long nv=0; while (nv < nvars) {
+          /* get next token and trim it from the values list. */
+        if (!strncmp(tok1,"char",4) || !strncmp(tok1,"material",8) ) {
+            char *iq1, *iq2;
+            iq1 = strchr(values,'"');
+            iq2 = strrchr(values,'"');
+            if (iq1 != NULL) {
+                strncpy(chvar[nv],iq1+1,iq2-iq1-1);
+                chvar[nv][iq2-iq1-1] = '\0';
+            }
+            else
+                strcpy(chvar[nv],values);
+        } else {
+            tokn = token(&values," \t");
+            if (tokn != NULL) {
+                if (!strncmp(tok1,"int",3)) rvar[nv] = atol(tokn);
+                if (!strcmp(tok1,"real"))   rvar[nv] = atof(tokn);
+                if (!strcmp(tok1,"double")) dvar[nv] = atof(tokn);
+            }
+        }
+        nv++;
+    }
+}
+
+/****************************************************************************/
+
+static void getmembers(long nmems)
+{
+    char *tokn, *iq1, *iq2;
+    long n, nq, nv=0;
+    /* fill string interiors with '@' so they are delineated as tokens */
+    n=0; nq=0; while (n<strlen(values)) {
+        if (values[n]=='"') nq++;
+        if ((values[n]==' '||values[n]=='\t') && nq%2==1) values[n] = '@';
+        n++;
+    }
+    while (nv < nmems) {
+          /* get next token and trim it from the values list. */
+        tokn = token(&values," \t");
+        if ( tokn[0]=='"' ) {
+            n=0; while (n<strlen(tokn))
+                { if (tokn[n]=='@') tokn[n] = ' '; n++; }
+            iq1 = strchr(tokn,'"');
+            iq2 = strrchr(tokn,'"');
+            strncpy(chvar[nv],iq1+1,iq2-iq1-1);
+            chvar[nv][iq2-iq1-1] = '\0';
+        } else {
+            strcpy(chvar[nv],tokn);
+        }
+        rvar[nv] = atof(tokn);
+        nv++;
+    }
+}
+
+/****************************************************************************/
+static void dbin_debug()
+{
+    debug_on = 1;
+}
+
+/****************************************************************************/
+static void chrcat(char* str, char chr)
+{
+    int ln;
+    ln = strlen(str);
+    str[ln] = chr;
+    str[ln+1]='\0';
+}
+
+/****************************************************************************/
+static char * stlower(char* st) {
+  int i=0;
+  while (st[i] != '\0') {
+    if (st[i] >= 'A' && st[i] <= 'Z') st[i] = st[i] + 'a' - 'A';
+    i++;
+  }
+  return st;
+}
+
+/****************************************************************************/
+static char* token(char** str, char* sep)
+{
+    int i=0;
+    char *if1=NULL, *if2=NULL, *strend = *str + strlen(*str);
+    /* if1 = rel. pointer to 1st token char */
+    i=0; while (if1 == NULL && i<strlen(*str)) {
+        if (!testsep(*(*str+i),sep))
+            if1= *str+i;
+        i++;
+    }
+    if (if1 == NULL) return if1;
+    /* if2 = 1st char past the token */
+    i=0; while (if2 == NULL && i<strlen(if1)) 
+        { if (testsep(if1[i],sep)) if2=&if1[i]; i++; }
+    if (if2<strend && if2 != NULL) {
+        if (if2 != NULL) *if2 = '\0';
+        *str = if2+1;
+    } else {
+        *str = strend;
+    }
+    return if1;
+}
+
+/****************************************************************************/
+static int testsep(char chr, char *sep)
+{
+    int ist=0, i=0;
+    while (sep[i] != '\0')
+        if (sep[i++] == chr || chr == '\0' || chr == '\n' ) ist=1;
+    return ist;
+}
+/***  Database read routine  ***/
+/***    Generated automatically using the dbin tool. */
+/***    Not to be modified by user. */
+/*
+** Modifiedt by P.L., to abe able to load all the templates into 
+** one file... And included in this file, to avoid defining too many 
+** global symbols.  This clearly breaks the dbin mold, to be discussed 
+** later.. 
+*/
+void mcf_ntubldRead(char* fname)
+{
+  void (*pf)(); /* pointer to interpreter */
+  inc_depth = 0;
+  n_instance =0;
+  lnlen=0; 
+  debug_on = 0;  
+  pf = &mcf_ntubld_interpret;
+  mcf_ntubldInit();
+  n_instance_line_title = 0;
+  n_instance_header = 0;
+  n_instance_variable = 0;
+  dbin_getrec(&fname,pf);
+}
+static void mcf_ntubld_interpret()
+{
+int inum, index, i, iok;
+iok=0;
+if ( !strcmp(varname,"TEMPLATE_line_title") ) {
+  inum = 0; iok = 1;
+  getmembers(n_el_line_title);
+  index = n_instance_line_title;
+  *n_obj_line_title = n_instance_line_title+1;
+  strcpy(line_title[index].line,chvar[inum++]);
+  n_instance_line_title++;
+}
+if ( !strcmp(varname,"TEMPLATE_header") ) {
+  inum = 0; iok = 1;
+  getmembers(n_el_header);
+  index = n_instance_header;
+  *n_obj_header = n_instance_header+1;
+  strcpy(header[index].title,chvar[inum++]);
+  strcpy(header[index].version,chvar[inum++]);
+  strcpy(header[index].namemaxindex,chvar[inum++]);
+  header[index].maxmult = rvar[inum++];
+  header[index].orgstyle = rvar[inum++];
+  header[index].nvar = rvar[inum++];
+  n_instance_header++;
+}
+if ( !strcmp(varname,"TEMPLATE_variable") ) {
+  inum = 0; iok = 1;
+  getmembers(n_el_variable);
+  index = n_instance_variable;
+  *n_obj_variable = n_instance_variable+1;
+  strcpy(variable[index].name,chvar[inum++]);
+  strcpy(variable[index].description,chvar[inum++]);
+  variable[index].type = rvar[inum++];
+  strcpy(variable[index].isfixedsize,chvar[inum++]);
+  variable[index].numdim = rvar[inum++];
+  for (i=0;i<5;i++) variable[index].dimensions[i] = rvar[inum++];
+  n_instance_variable++;
+}
+}
Index: /trunk/Utilities/mcfio/mcf_ntuBldDbinc.h
===================================================================
--- /trunk/Utilities/mcfio/mcf_ntuBldDbinc.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_ntuBldDbinc.h	(revision 3)
@@ -0,0 +1,21 @@
+/*
+ *     dbin.h
+ *
+ *  C++ utility routines for the dbin package: see dbin.lex
+ *
+ *  N.B. The Strings class from the CLHEP library is used.
+ *
+ *       Torre Wenaus 04/01/1994
+ *
+ * Modifications:
+ * 8/21/95   T. Wenaus Mod history started
+ * 8/21/95   TW        Strings class removed from dbin generated code.
+ * 8/22/95   TW        Strings class removed from dbinc.cc
+ *
+ * November 1995: some clean up to be able to run this code and 
+ * standard dbin simulateneously..
+ * Make some routine & variable static, and change the name of routine 
+ * called from the outside, following the Nirvana/mcfio conventions.
+ * 
+ */
+void mcf_ntubldRead(char* fname);
Index: /trunk/Utilities/mcfio/mcf_ntubldInit.c
===================================================================
--- /trunk/Utilities/mcfio/mcf_ntubldInit.c	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_ntubldInit.c	(revision 3)
@@ -0,0 +1,31 @@
+/***  Database default init routine  ***/
+/***  Generated automatically using the dbin tool. */
+/***  Not to be modified by user. */
+#include "mcf_ntubld_db.h"
+void mcf_ntubldInit() {
+
+/***** template line_title *****/
+/*   char line " "  */
+/* end template */
+*n_obj_line_title=0;
+
+/***** template header *****/
+/*     char title  */
+/*     char version */
+/*     char nameMaxIndex */
+/*     int maxMult */
+/*     int orgStyle */
+/*     int nVar */
+/* end template */
+*n_obj_header=0;
+
+/***** template variable *****/
+/*     char name  */
+/*     char description  */
+/*     int  type    */
+/*     char isFixedSize */
+/*     int  numDim  */
+/*     int  dimensions(5) */
+/* end template  */
+*n_obj_variable=0;
+}
Index: /trunk/Utilities/mcfio/mcf_ntubld_db.h
===================================================================
--- /trunk/Utilities/mcfio/mcf_ntubld_db.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_ntubld_db.h	(revision 3)
@@ -0,0 +1,57 @@
+#ifndef _mcf_tmp_INC
+#define _mcf_tmp_INC
+
+
+/***** template line_title *****/
+
+typedef struct _line_title_s {
+  char line[80]; /*  */
+} line_title_s;
+static const int n_el_line_title=1;
+extern struct line_title_c {
+  int n_obj_line_title;
+  int idmline_title;
+  line_title_s line_title[500];
+} line_title_c_;
+static int *n_obj_line_title = &(line_title_c_.n_obj_line_title);
+static line_title_s *line_title = &line_title_c_.line_title[0];
+
+/***** template header *****/
+
+typedef struct _header_s {
+  char title[80]; /*  */
+  char version[80]; /*  */
+  char namemaxindex[80]; /*  */
+  int maxmult; /*  */
+  int orgstyle; /*  */
+  int nvar; /*  */
+} header_s;
+static const int n_el_header=6;
+extern struct header_c {
+  int n_obj_header;
+  int idmheader;
+  header_s header[1];
+} header_c_;
+static int *n_obj_header = &(header_c_.n_obj_header);
+static header_s *header = &header_c_.header[0];
+
+/***** template variable *****/
+
+typedef struct _variable_s {
+  char name[80]; /*  */
+  char description[80]; /*  */
+  int type; /*  */
+  char isfixedsize[80]; /*  */
+  int numdim; /*  */
+  int dimensions[5]; /*  */
+} variable_s;
+static const int n_el_variable=10;
+extern struct variable_c {
+  int n_obj_variable;
+  int idmvariable;
+  variable_s variable[100];
+} variable_c_;
+static int *n_obj_variable = &(variable_c_.n_obj_variable);
+static variable_s *variable = &variable_c_.variable[0];
+
+#endif
Index: /trunk/Utilities/mcfio/mcf_xdr.h
===================================================================
--- /trunk/Utilities/mcfio/mcf_xdr.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_xdr.h	(revision 3)
@@ -0,0 +1,185 @@
+/*******************************************************************************
+*									       *
+* mcf_xdr.h --  Include file for mcfast Xdr layer. Specifies the headers     *
+*                 ( Block, event, table and files) 			       *	       *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warrenty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*									       *
+*******************************************************************************/
+#define MCF_XDR_F_TITLE_LENGTH 255
+#define MCF_XDR_B_TITLE_LENGTH 80
+#define MCF_XDR_MAXLREC 32000
+#define MCF_XDR_MINLREC 512
+#define MCF_XDR_VERSION "v0.0"
+#define MCF_STREAM_NUM_MAX 20
+#define MCF_DEFAULT_TABLE_SIZE 100
+#define MCF_XDR_VERSION_LENGTH 4
+#define MCF_XDR_STDCM2_LENGTH 20
+#define XDR_MCFIOCODE 1025 /* Private code to be passed to the encoding  
+				filter to estimate the length prior to encode
+				in memory */ 
+
+typedef enum _mcfxdrBlockType { 
+	GENERIC, FILEHEADER, EVENTTABLE, SEQUENTIALHEADER, 
+	EVENTHEADER, NOTHING
+} mcfxdrBlockType;
+
+
+typedef struct _mcfxdrGeneric{
+	int id;		/* Identifier for this item =  FILEHEADER */
+	int length;     /* The length of data body, byte count, excluding 
+				the id and version, and this word */
+	char version[MCF_XDR_VERSION_LENGTH+1];
+	                /* The version of this particular block */
+	int *data;	/* The data block */
+} mcfxdrGeneric;
+
+typedef struct _mcfxdrFileHeader{
+	int id;		/* Identifier for this item =  FILEHEADER */
+	int length;     /* The length of data body, byte count, excluding 
+				the id and version, and this word */
+	char version[MCF_XDR_VERSION_LENGTH+1];
+	                /* The version of this particular block */
+	char title[MCF_XDR_F_TITLE_LENGTH+1];
+		        /* The title length */
+	char comment[MCF_XDR_F_TITLE_LENGTH+1]; /* The comment ..*/
+	char date[30];
+	char closingDate[30];
+	unsigned int numevts_expect;    /* The number of event expected */
+	unsigned int numevts;    /* The number of evts really written on tape */
+	unsigned int firstTable; /* The XDR locator for the first table */
+	unsigned int dimTable; /* The number of events listed in the fixed-sized 
+	                           event table */
+	unsigned int nBlocks;		
+			/* The maximum number of Block types in the file
+				( excluding File headers and Event Tables) */
+	int *blockIds;     /* The list of Block identifiers */
+	
+	char **blockNames; /* The list of names ( Titles) for these blocks */
+	unsigned int nNTuples;
+	                /* The maximum number of Ntuples defined for this 
+	                	stream */
+	
+} mcfxdrFileHeader;
+
+typedef struct _mcfxdrEventTable{
+	int id;		/* Identifier for this item =  EVENTTABLE */
+	int length;     /* The length of data body, byte count, excluding 
+				the id and version, and this word */
+	char version[MCF_XDR_VERSION_LENGTH+1];
+	                 /* The version of this particular block */
+	int nextLocator; /*The Locator for the next Event Table. */
+	int previousnumevts; /* The size of the previous Table */
+        int numevts;	/* The number of events in this chunk */
+        unsigned int dim; /* The dimension of the arrays listed below */
+	unsigned int ievt;     /* The current index in the list */
+	int *evtnums;	/* The List of event numbers, within a store */
+	int *storenums; /* The list of Store number within a Run */
+	int *runnums;   /* The list of run numbers */
+	int *trigMasks; /* The list of user-defined Trigger masks */
+	unsigned int *ptrEvents;
+			/* The list of XDR pointers for these events */ 
+} mcfxdrEventTable;
+
+typedef struct _mcfxdrSequentialHeader{
+	int id;		/* Identifier for this item =  SEQUENTIALHEADER */
+	int length;     /* The length of data body, byte count, excluding 
+				the id and version, and this word */
+	char version[MCF_XDR_VERSION_LENGTH+1];
+	               /* The version of this particular block */
+	unsigned int nRecords; /* The number of records (including this one) 
+				in the logical event */			
+} mcfxdrSequentialHeader;
+ 
+typedef struct _mcfxdrEventHeader{
+	int id;		/* Identifier for this item =  CHUNKHEADER */
+	int length;     /* The length of data body, byte count, excluding 
+				the id and version, and this word */
+	char version[MCF_XDR_VERSION_LENGTH+1];
+	               /* The version of this particular block */
+	int previousevtnum; /* The previous event number */
+	int evtnum;	/* The event numbers, within a store */
+	int storenum;   /* The Store number within a Run */
+	int runnum;     /* The Run numbers */
+	int trigMask;  /* The Trigger masks */
+	unsigned int nBlocks;  /* The number of Blocks  */
+	unsigned int dimBlocks; /* The dimension of the two following arrays */
+	int *blockIds;     /* The list of Block identifiers */
+	unsigned int *ptrBlocks;
+			/* The list of XDR pointers for these blocks */ 
+	unsigned int nNTuples;
+	                /* The number of Ntuples defined for this event */
+	                
+	unsigned int dimNTuples; /* The dimension of the two following arrays */
+	int *nTupleIds; /* The list of Ntuple identifiers, pointing to the 
+				global list array */                				
+	unsigned int *ptrNTuples;
+			/* The list of XDR pointers for these NTuples */ 
+	
+} mcfxdrEventHeader;
+
+typedef struct _mcfStream{
+	int id; 	/* Id of the Stream */
+	int row;	/* Read or Write */
+	int dos;	/* Direct, Memory Mapped I/O or Sequential */
+	int status;     /* The Stream status, either at BOF, RUNNING, EOF 
+	                   or simply declared, and needs to be opened 
+	                   (NTuple usage) */
+	int numWordsC;  /* The number of words read or written, Content */
+	int numWordsT;  /* The number of words read or written, Total */
+	mcfxdrFileHeader *fhead; /* The File header */
+	mcfxdrEventHeader *ehead; /* The current Event Header */  
+	unsigned int currentPos; /* The XDR current position */
+	unsigned int evtPos;     /* The XDR position for the begingin of evt */
+	unsigned int tablePos;   /* The XDR position for the table */
+	unsigned int firstPos;   /* The XDR position just before file header */
+	XDR *xdr;       /* The XDR stream */
+	char *filename; /* Filename */
+	FILE *filePtr;  /* The file pointer */
+	int fileDescr;      /* File descriptor if Memory Mapped */
+	char *fileAddr;  /* Address in virtual memory if Memory Mapped */
+	size_t fileLen;   /* The file length */
+	mcfxdrEventTable *table; /* The event table */
+	char *device;	/* The device name, if any */
+	char *vsn;      /* The Visual S. number, e.g., the tape label */
+	int filenumber; /* The sequential file number, if any */
+	int minlrec;    /* The minimum record length for this stream */
+	int maxlrec;    /* The maximum record length for this stream */
+	int bufferSize; /* The current size of the primary buffer */	
+	mcfxdrSequentialHeader *shead; /* The Sequential header */
+	char *buffer;   /*  A pointer to a generic data buffer, to get the 
+				data from tape and then decode it */
+	char *buffer2; /* A secondary buffer, to hold the event 
+				as the event grows */
+} mcfStream;
+
+extern mcfStream **McfStreamPtrList;
+extern char **McfGenericVersion;
+extern unsigned int McfNumOfStreamActive;	 
+extern bool_t McfNTuPleSaveDecoding;
+
+bool_t xdr_mcfast_generic(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version, char** data);
+bool_t xdr_mcfast_headerBlock(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version);
+bool_t xdr_mcfast_fileheader(XDR *xdrs, int *blockid,
+ 		 int *ntot, char** version, mcfxdrFileHeader **mcf, 
+ 		 int streamId);
+bool_t xdr_mcfast_eventtable(XDR *xdrs, int *blockid,
+ 		 int *ntot, char** version, mcfxdrEventTable **mcf);
+bool_t xdr_mcfast_seqheader(XDR *xdrs, int *blockid,
+ 		 int *ntot, char** version, mcfxdrSequentialHeader **mcf);
+bool_t xdr_mcfast_eventheader(XDR *xdrs, int *blockid,
+ 		 int *ntot, char** version, mcfxdrEventHeader **mcf);
Index: /trunk/Utilities/mcfio/mcf_xdr_Ntuple.h
===================================================================
--- /trunk/Utilities/mcfio/mcf_xdr_Ntuple.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcf_xdr_Ntuple.h	(revision 3)
@@ -0,0 +1,32 @@
+/*******************************************************************************
+*									       *
+* mcf_xdr_Ntuple.h --  Include file for mcfast Xdrlayer used in the 	       *
+*       Ntuple code. Refers to a bunch of structure not included in this file. *	 Specifies the headers     *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warrenty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*									       *
+*******************************************************************************/
+bool_t xdr_mcfast_NTuple(XDR *xdrs, descrGenNtuple *dNTu,
+ 		 int *ntot, int nTupleId,  char* version);
+bool_t xdr_mcfast_NTupleXDRPtr(XDR *xdrs, descrGenNtuple *dNTu,
+ 		 int *ntot, int nTupleId,  char* version);
+bool_t xdr_mcfast_NTupleMult(mcfStream *str,
+                             descrGenNtuple *dNTu, char* version); 		 
+bool_t xdr_mcfast_NTupleVar(mcfStream *str,
+                           descrGenNtuple *dNTu, int ivar, char* version); 		 
+bool_t xdr_mcfast_NTupleSubVar(mcfStream *str,
+             descrGenNtuple *dNTu, int ivar, int multIndex, char* version);
+bool_t xdr_mcfast_NTupleSubStruct(mcfStream *str,
+             descrGenNtuple *dNTu, int multIndex, char* version);
Index: /trunk/Utilities/mcfio/mcfio_Block.c
===================================================================
--- /trunk/Utilities/mcfio/mcfio_Block.c	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_Block.c	(revision 3)
@@ -0,0 +1,488 @@
+/*******************************************************************************
+*									       *
+* mcfio_Block.c --  Utility routines for the McFast Monte-Carlo                  *
+*		The routine to encode/decode a block 	                       *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Paul Lebrun						       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <rpc/xdr.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <time.h>
+#ifdef SUNOS
+#include <floatingpoint.h>
+#else /* SUNOS */
+#include <float.h>
+#endif /* SUNOS */
+#include "mcf_nTupleDescript.h"
+#include "mcf_xdr.h"
+#include "mcf_xdr_Ntuple.h"
+#include "mcfio_Dict.h"
+#include "mcfio_Util1.h"
+#include "mcf_NTuIOUtils.h"
+#include "mcfio_Direct.h"
+#include "mcfio_Block.h"
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+int mcfioC_Block(int stream, int blkid, 
+ bool_t xdr_filtercode(XDR *xdrs, int *blockid, int *ntot, char **version))
+/*
+** Routine to decode or encode a particular Block. Return 1 if O.K, 
+** -1 if a problem or unknow block.  
+**
+** Adding Ntuple instances ... October 1995.
+*/
+{ 
+  int i, j, jstr, idtmp, ntot, nbuff;
+  bool_t ok;
+  u_int p1;
+  mcfStream *str;
+   
+  if (McfStreamPtrList == NULL) { 
+     fprintf(stderr,
+  " mcfio_Block: You must first initialize by calling mcfio_Init.\n"); 
+     return -1;
+  }
+  jstr = stream-1;
+  if (McfStreamPtrList[jstr] == NULL) { 
+     fprintf(stderr,
+ " mcfio_Block: First, declare the stream by calling mcfio_Open...\n"); 
+     return -1;
+  }
+  str = McfStreamPtrList[jstr];
+  if ((str->row == MCFIO_WRITE) && 
+      (str->fhead->nBlocks == str->ehead->nBlocks)) {
+     fprintf(stderr,
+ " mcfio_Block: Maximum number of Blocks reached for stream %d ...\n", stream);
+     fprintf(stderr,
+ "              Please upgrade the declaration mcfio_Open statement \n");
+     return -1;
+  }
+     
+  if (str->row == MCFIO_READ) {
+      for(i=0, j=-1; i<str->ehead->nBlocks; i++) {
+           if (str->ehead->blockIds[i] == blkid) j = i;
+        }
+      if (j == -1) {
+/*
+        fprintf(stderr,
+ " mcfio_Block: Unable to find block i.d. %d in Stream %d \n", blkid, stream);
+*/
+          return -1;  
+      }
+      if (xdr_setpos(str->xdr,str->ehead->ptrBlocks[j]) == FALSE) {
+        fprintf(stderr,
+         " mcfio_Block: Unable to position stream at block %d \n", blkid);
+          return -1;  
+      }
+      str->currentPos = str->ehead->ptrBlocks[j];
+  } else if (str->row == MCFIO_WRITE)  {
+      idtmp = blkid;
+      /*
+      ** if to Sequential media, one first has to make sure we have 
+      ** enough room in the buffer.
+      */
+      if (str->dos == MCFIO_SEQUENTIAL) {
+         str->xdr->x_op = XDR_MCFIOCODE;
+         ok = xdr_filtercode(str->xdr, &idtmp, &ntot, McfGenericVersion);
+         str->xdr->x_op = XDR_ENCODE;
+         if ((str->currentPos + 4*(ntot + 1)) > str->bufferSize) {
+          /*
+          ** Once again, I don't trust realloc, got to copy to the second 
+          ** buffer. 
+          */
+             nbuff = 1 + 
+                    (((4*(ntot + 1)) + (str->currentPos - str->firstPos))/
+                       str->maxlrec);
+             str->buffer2 = 
+                 (char *) malloc (sizeof(char) * (str->maxlrec *nbuff));
+             memcpy(str->buffer2, str->buffer, 
+                       (str->currentPos - str->firstPos));
+             free(str->buffer);
+             str->buffer = str->buffer2;
+             str->buffer2 = NULL;
+             str->bufferSize = str->maxlrec * nbuff;
+             xdrmem_create(str->xdr, str->buffer, str->bufferSize, XDR_ENCODE);
+             if (xdr_setpos(str->xdr, str->currentPos) == FALSE) {
+                 fprintf(stderr,
+             " mcfio_Block:\n\
+ Unable to position stream %d at block %d after realocation.\n", stream, blkid);
+                 return -1; 
+             } 
+          }
+       }
+   }
+   p1 = str->currentPos;
+   ok = xdr_filtercode(str->xdr, &idtmp, &ntot, McfGenericVersion);
+   if (ok == FALSE) {
+        fprintf(stderr,
+         " mcfio_Block: Unable to encode or decode block I.D. %d \n", blkid);
+         j = str->ehead->nBlocks;
+         if (xdr_setpos(str->xdr,p1) == FALSE) 
+           fprintf(stderr,
+         " mcfio_Block: Unable to position stream at block %d \n", blkid);
+         return -1;
+      }
+   if(blkid != idtmp) {
+        fprintf(stderr,
+         " mcfio_Block: Unexpected I.D = %d found instead of I.D. %d \n",
+              idtmp, blkid);
+        return -1;
+      }
+    if (str->row == MCFIO_WRITE)  {  
+      str->ehead->blockIds[str->ehead->nBlocks] = blkid;
+      str->ehead->ptrBlocks[str->ehead->nBlocks] = p1;
+      str->ehead->nBlocks++; 
+    }
+    str->currentPos = xdr_getpos(str->xdr);    
+    str->numWordsC += (ntot/4);
+    str->numWordsT += ((str->currentPos-p1)/4);
+    return 1;
+        
+}
+int mcfioC_NTuple(int stream, int nTupleId, char * version)
+{ 
+  int i, j, jstr, ntot, nbuff;
+  bool_t ok;
+  u_int p1;
+  mcfStream *str;
+  nTuDDL *ddl;
+  descrGenNtuple *dNTu;
+     
+  if (McfStreamPtrList == NULL) { 
+     fprintf(stderr,
+  " mcfio_NTuple: You must first initialize by calling mcfio_Init.\n"); 
+     return -1;
+  }
+  jstr = stream-1;
+  if (McfStreamPtrList[jstr] == NULL) { 
+     fprintf(stderr,
+ " mcfio_NTuple: First, declare the stream by calling mcfio_Open...\n"); 
+     return -1;
+  }
+  
+  ddl = mcf_GetNTuByStreamID(stream, nTupleId);
+  if (ddl == NULL) {
+     fprintf(stderr,
+ " mcfio_NTuple: Illegal or inexistant NTuple Id %d for stream %d \n", 
+     nTupleId, stream); 
+     return -1;
+  }
+  if (ddl->reference == NULL) dNTu = ddl->descrNtu;
+  else dNTu = ddl->reference->descrNtu;
+  str = McfStreamPtrList[jstr];
+  if ((str->row == MCFIO_WRITE) && 
+      (str->fhead->nNTuples == str->ehead->nNTuples)) {
+     fprintf(stderr,
+" mcfio_NTuple: Maximum number of NTuples reached for stream %d ...\n", stream);
+     fprintf(stderr,
+ "              Please upgrade the Ntuple declarations statements. \n");
+     return -1;
+  }
+     
+  if (str->row == MCFIO_READ) {
+      for(i=0, j=-1; i<str->ehead->nNTuples; i++) {
+           if (str->ehead->nTupleIds[i] == ddl->seqNTuId) j = i;
+        }
+      if (j == -1) {
+        fprintf(stderr,
+ " mcfio_NTuple: Unable to find NTuple i.d. %d in Stream %d \n",
+          nTupleId, stream);
+          return -1;  
+      }
+      if (xdr_setpos(str->xdr,str->ehead->ptrNTuples[j]) == FALSE) {
+        fprintf(stderr,
+         " mcfio_NTuple: Unable to position stream at NTuple %d \n", nTupleId);
+          return -1;  
+      }
+      str->currentPos = str->ehead->ptrNTuples[j];
+  } else if (str->row == MCFIO_WRITE)  {
+      /*
+      ** if to Sequential media, one first has to make sure we have 
+      ** enough room in the buffer.
+      */
+      if (str->dos == MCFIO_SEQUENTIAL) {
+         str->xdr->x_op = XDR_MCFIOCODE;
+         ok = xdr_mcfast_NTuple(str->xdr, dNTu, &ntot,
+                                 ddl->seqNTuId, version);
+         str->xdr->x_op = XDR_ENCODE;
+         if (ok == FALSE) {
+             fprintf(stderr,
+ "mcfio_NTuple: can not Encode or Decode Ntuple id %d on Seq. Stream %d ", 
+             nTupleId, stream);
+             return -1;
+         }
+         if ((str->currentPos + 4*(ntot + 1)) > str->bufferSize) {
+          /*
+          ** Once again, I don't trust realloc, got to copy to the second 
+          ** buffer. 
+          */
+             nbuff = 1 + 
+                    (((4*(ntot + 1)) + (str->currentPos - str->firstPos))/
+                       str->maxlrec);
+             str->buffer2 = 
+                 (char *) malloc (sizeof(char) * (str->maxlrec *nbuff));
+             memcpy(str->buffer2, str->buffer, 
+                       (str->currentPos - str->firstPos));
+             free(str->buffer);
+             str->buffer = str->buffer2;
+             str->buffer2 = NULL;
+             str->bufferSize = str->maxlrec * nbuff;
+             xdrmem_create(str->xdr, str->buffer, str->bufferSize, XDR_ENCODE);
+             if (xdr_setpos(str->xdr, str->currentPos) == FALSE) {
+                 fprintf(stderr,
+             " mcfio_NTuple:\n\
+ Unable to position stream %d at Ntuple %d after realocation.\n",
+                 stream, nTupleId);
+                 return -1; 
+             } 
+          }
+       }
+   }
+   p1 = str->currentPos;
+   ok = xdr_mcfast_NTuple(str->xdr, dNTu, &ntot, ddl->seqNTuId, version);
+   if (ok == FALSE) {
+        fprintf(stderr,
+         " mcfio_NTuple: Unable to encode or decode NTuple I.D. %d \n",
+             nTupleId);
+         j = str->ehead->nNTuples;
+         if (xdr_setpos(str->xdr,p1) == FALSE) 
+           fprintf(stderr,
+         " mcfio_NTuple: Unable to position stream at NTuple %d \n", nTupleId);
+         return -1;
+      }
+    if (str->row == MCFIO_WRITE)  {  
+      str->ehead->nTupleIds[str->ehead->nNTuples] = ddl->seqNTuId;
+      str->ehead->ptrNTuples[str->ehead->nNTuples] = p1;
+      str->ehead->nNTuples++; 
+    }
+    str->currentPos = xdr_getpos(str->xdr);    
+    str->numWordsC += (ntot/4);
+    str->numWordsT += ((str->currentPos-p1)/4);
+    return 1;
+        
+}
+/*
+** Optimized version used exclusively to read the multiplicity value 
+** within an NTuple. It is assumed that the stream is open read direct 
+** access (No checks!), and the event table is available, and the 
+** NTuple is accessible.  Once again, No checks! Use at your onw risk.
+** Also, we do not keep record of the number of byte Read.  
+*/
+int mcfioC_NTupleMult(int stream, int nTupleId, char * version)
+{ 
+  int i, j, jstr, ntot;
+  bool_t ok;
+  mcfStream *str;
+  nTuDDL *ddl;
+  descrGenNtuple *dNTu;
+     
+  jstr = stream-1;
+  ddl = mcf_GetNTuByStreamID(stream, nTupleId);
+  if (ddl->reference == NULL) dNTu = ddl->descrNtu;
+  else dNTu = ddl->reference->descrNtu;
+  str = McfStreamPtrList[jstr];
+  for(i=0, j=-1; i<str->ehead->nNTuples; i++) {
+           if (str->ehead->nTupleIds[i] == ddl->seqNTuId) j = i;
+   }
+  if (xdr_setpos(str->xdr,str->ehead->ptrNTuples[j]) == FALSE) {
+        fprintf(stderr,
+    " mcfio_NTupleMult: Unable to position stream at NTuple %d \n", nTupleId);
+          return -1;  
+      }
+  str->currentPos = str->ehead->ptrNTuples[j];
+  if (dNTu->multXDROffset == 0) 
+      ok = xdr_mcfast_NTupleXDRPtr(str->xdr, dNTu, &ntot,
+                                   ddl->seqNTuId, version);
+   else ok = xdr_mcfast_NTupleMult(str, dNTu, version);
+   if (ok == FALSE) {
+        fprintf(stderr,
+         " mcfio_NTuple: Unable to encode or decode NTuple I.D. %d \n",
+             nTupleId);
+         j = str->ehead->nNTuples;
+         if (xdr_setpos(str->xdr, str->currentPos) == FALSE) 
+           fprintf(stderr,
+         " mcfio_NTuple: Unable to position stream at NTuple %d \n", nTupleId);
+         return -1;
+      }
+      /*
+      ** This probably could be optimized away. Note the that the current 
+      ** position of the stream strored in str->currentPos is no longer 
+      ** valied exiting this routine. However, there is enough redundancy 
+      ** in the data structure to figure out where we could go..
+      */
+     /*  xdr_setpos(str->xdr, str->currentPos);   */ 
+    return TRUE;
+        
+}
+            
+/*
+** Optimized version used exclusively to read a specific variable  
+** within an NTuple. Valid only if the variable is of fixed size 
+** (e.g. not indexed by multiplicity) or if the data structure organization is
+** of type parallel array. It is assumed that the stream is open read direct 
+** access (No checks!), and the event table is available, and the 
+** NTuple is accessible.  Once again, No checks! Use at your own risk.
+*/
+int mcfioC_NTupleVar(int stream, int nTupleId, int ivar, char * version)
+{ 
+  int i, j, jstr, ntot;
+  bool_t ok;
+  mcfStream *str;
+  nTuDDL *ddl;
+  descrGenNtuple *dNTu;
+     
+  jstr = stream-1;
+  ddl = mcf_GetNTuByStreamID(stream, nTupleId);
+  if (ddl->reference == NULL) dNTu = ddl->descrNtu;
+  else dNTu = ddl->reference->descrNtu;
+  str = McfStreamPtrList[jstr];
+  for(i=0, j=-1; i<str->ehead->nNTuples; i++) {
+           if (str->ehead->nTupleIds[i] == ddl->seqNTuId) j = i;
+   }
+  if (xdr_setpos(str->xdr,str->ehead->ptrNTuples[j]) == FALSE) {
+        fprintf(stderr,
+    " mcfio_NTupleVar: Unable to position stream at NTuple %d \n", nTupleId);
+          return -1;  
+      }
+  str->currentPos = str->ehead->ptrNTuples[j];
+  if (dNTu->multXDROffset == 0) 
+      ok = xdr_mcfast_NTupleXDRPtr(str->xdr, dNTu, &ntot,
+                                   ddl->seqNTuId, version);
+   else ok = xdr_mcfast_NTupleVar(str, dNTu, ivar, version);
+   if (ok == FALSE) {
+        fprintf(stderr,
+         " mcfio_NTuple: Unable to encode or decode NTuple I.D. %d \n",
+             nTupleId);
+         j = str->ehead->nNTuples;
+         if (xdr_setpos(str->xdr, str->currentPos) == FALSE) 
+           fprintf(stderr,
+         " mcfio_NTuple: Unable to position stream at NTuple %d \n", nTupleId);
+         return -1;
+      }
+    return TRUE;
+        
+}
+/*
+** Optimized version used exclusively to read a specific variable within a  
+** substructure within an NTuple. Valid only if of type indexed  
+** and if the data structure organization is
+** of type VAX FORTRAN d/s. It is assumed that the stream is open read direct 
+** access (No checks!), and the event table is available, and the 
+** NTuple is accessible.  Once again, No checks! Use at your own risk.
+*/
+int mcfioC_NTupleSubVar(int stream, int nTupleId, int ivar, int multIndex,
+                               char * version)
+{ 
+  int i, j, jstr, ntot;
+  bool_t ok;
+  mcfStream *str;
+  nTuDDL *ddl;
+  descrGenNtuple *dNTu;
+     
+  jstr = stream-1;
+  ddl = mcf_GetNTuByStreamID(stream, nTupleId);
+  if (ddl->reference == NULL) dNTu = ddl->descrNtu;
+  else dNTu = ddl->reference->descrNtu;
+  str = McfStreamPtrList[jstr];
+  for(i=0, j=-1; i<str->ehead->nNTuples; i++) {
+           if (str->ehead->nTupleIds[i] == ddl->seqNTuId) j = i;
+   }
+  if (xdr_setpos(str->xdr,str->ehead->ptrNTuples[j]) == FALSE) {
+        fprintf(stderr,
+    " mcfio_NTupleVar: Unable to position stream at NTuple %d \n", nTupleId);
+          return -1;  
+      }
+  str->currentPos = str->ehead->ptrNTuples[j];
+  if (dNTu->multXDROffset == 0) 
+      ok = xdr_mcfast_NTupleXDRPtr(str->xdr, dNTu, &ntot,
+                                   ddl->seqNTuId, version);
+   else ok = xdr_mcfast_NTupleSubVar(str, dNTu, ivar, multIndex, version);
+   if (ok == FALSE) {
+        fprintf(stderr,
+         " mcfio_NTuple: Unable to encode or decode NTuple I.D. %d \n",
+             nTupleId);
+         j = str->ehead->nNTuples;
+         if (xdr_setpos(str->xdr, str->currentPos) == FALSE) 
+           fprintf(stderr,
+         " mcfio_NTuple: Unable to position stream at NTuple %d \n", nTupleId);
+         return -1;
+      }
+    return TRUE;
+        
+}
+/*
+** Optimized version used exclusively to read a specific   
+** substructure within an NTuple. Valid only if of type indexed  
+** and if the data structure organization is
+** of type VAX FORTRAN d/s. It is assumed that the stream is open read direct 
+** access (No checks!), and the event table is available, and the 
+** NTuple is accessible.  Once again, No checks! Use at your own risk.
+*/
+int mcfioC_NTupleSubStruct(int stream, int nTupleId, int multIndex,
+                               char * version)
+{ 
+  int i, j, jstr, ntot;
+  bool_t ok;
+  mcfStream *str;
+  nTuDDL *ddl;
+  descrGenNtuple *dNTu;
+     
+  jstr = stream-1;
+  ddl = mcf_GetNTuByStreamID(stream, nTupleId);
+  if (ddl->reference == NULL) dNTu = ddl->descrNtu;
+  else dNTu = ddl->reference->descrNtu;
+  str = McfStreamPtrList[jstr];
+  for(i=0, j=-1; i<str->ehead->nNTuples; i++) {
+           if (str->ehead->nTupleIds[i] == ddl->seqNTuId) j = i;
+   }
+  if (xdr_setpos(str->xdr,str->ehead->ptrNTuples[j]) == FALSE) {
+        fprintf(stderr,
+    " mcfio_NTupleVar: Unable to position stream at NTuple %d \n", nTupleId);
+          return -1;  
+      }
+  str->currentPos = str->ehead->ptrNTuples[j];
+  if (dNTu->multXDROffset == 0) 
+      ok = xdr_mcfast_NTupleXDRPtr(str->xdr, dNTu, &ntot,
+                                   ddl->seqNTuId, version);
+   else ok = xdr_mcfast_NTupleSubStruct(str, dNTu, multIndex, version);
+   if (ok == FALSE) {
+        fprintf(stderr,
+         " mcfio_NTuple: Unable to encode or decode NTuple I.D. %d \n",
+             nTupleId);
+         j = str->ehead->nNTuples;
+         if (xdr_setpos(str->xdr, str->currentPos) == FALSE) 
+           fprintf(stderr,
+         " mcfio_NTuple: Unable to position stream at NTuple %d \n", nTupleId);
+         return -1;
+      }
+    return TRUE;
+        
+}
Index: /trunk/Utilities/mcfio/mcfio_Block.h
===================================================================
--- /trunk/Utilities/mcfio/mcfio_Block.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_Block.h	(revision 3)
@@ -0,0 +1,19 @@
+/*******************************************************************************
+*									       *
+* mcfio_Block.h --  Include file for mcfast Direct i/o layer. 		       *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+*									       *
+*******************************************************************************/
+int mcfioC_Block(int stream, int blkid, 
+ bool_t xdr_filtercode(XDR *xdrs, int *blockid, int *ntot, char **version));
+int mcfioC_NTuple(int stream, int nTupleid, char * version); 
+int mcfioC_NTupleMult(int stream, int nTupleid, char * version);
+int mcfioC_NTupleVar(int stream, int nTupleid, int ivar, char * version);
+int mcfioC_NTupleSubVar(int stream, int nTupleid, int ivar, int multIndex,
+                           char * version);
+int mcfioC_NTupleSubStruct(int stream, int nTupleid, int multIndex,
+                           char * version);
+ 
+
Index: /trunk/Utilities/mcfio/mcfio_Dict.h
===================================================================
--- /trunk/Utilities/mcfio/mcfio_Dict.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_Dict.h	(revision 3)
@@ -0,0 +1,57 @@
+/*******************************************************************************
+*									       *
+* mcfio_dict.h --  Dictionary for Key words used in Info routines.             *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+*									       *
+*******************************************************************************/
+#define MCFIO_VERSION 100
+#define MCFIO_STATUS 101
+#define MCFIO_RUNNING 102
+#define MCFIO_BOF 103
+#define MCFIO_EOF 104
+#define MCFIO_NUMBLOCKS 501
+#define MCFIO_READORWRITE 502
+#define MCFIO_READ 1
+#define MCFIO_WRITE 2
+#define MCFIO_DIRECTORSEQUENTIAL 503
+#define MCFIO_DIRECT 1
+#define MCFIO_SEQUENTIAL 2
+#define MCFIO_MEMMAPPED 3
+#define MCFIO_BLOCKIDS 504
+#define MCFIO_NUMWORDS 505
+#define MCFIO_EFFICIENCY 506
+#define MCFIO_NUMEVTS 507
+#define MCFIO_FILENUMBER 508
+#define MCFIO_MAXREC 509
+#define MCFIO_MINREC 510
+#define MCFIO_NUMRECORDS 511
+#define MCFIO_RECORDLENGTHS 512
+#define MCFIO_TITLE 1001
+#define MCFIO_COMMENT 1002
+#define MCFIO_CREATIONDATE 1003
+#define MCFIO_CLOSINGDATE 1013
+#define MCFIO_FILENAME 1004
+#define MCFIO_DEVICENAME 1005
+#define MCFIO_EVENTNUMBER 2001
+#define MCFIO_STORENUMBER 2002
+#define MCFIO_RUNNUMBER 2003
+#define MCFIO_TRIGGERMASK 2004
+#define MCFIO_NUMNTUPLES 4001
+#define MCFIO_NTUPLESLIST 4002
+/*
+** Block definition now. Start counting at 101 See also mcfioC_GetBlockNames
+*/
+#define MCFIO_STDHEP 101
+#define MCFIO_OFFTRACKARRAYS 102
+#define MCFIO_OFFTRACKSTRUCT 103
+#define MCFIO_TRACEARRAYS    104
+#define MCFIO_STDHEPM 105
+#define MCFIO_STDHEPBEG 106
+#define MCFIO_STDHEPEND 107
+#define MCFIO_STDHEPCXX 108
+#define MCFIO_STDHEP4 201
+#define MCFIO_STDHEP4M 202
+#define MCFIO_HEPEUP 203
+#define MCFIO_HEPRUP 204
Index: /trunk/Utilities/mcfio/mcfio_Direct.c
===================================================================
--- /trunk/Utilities/mcfio/mcfio_Direct.c	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_Direct.c	(revision 3)
@@ -0,0 +1,1025 @@
+/*******************************************************************************
+*									       *
+* mcfio_Direct.c --  Utility routines for the McFast Monte-Carlo                 *
+*		Direct Access I/O core routines 	                       *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Paul Lebrun						       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <rpc/xdr.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#ifdef SUNOS
+#include <floatingpoint.h>
+#else /* SUNOS */
+#include <float.h>
+#endif /* SUNOS */
+#include "mcf_nTupleDescript.h"
+#include "mcf_xdr.h"
+#include "mcfio_Dict.h"
+#include "mcfio_Util1.h"
+#include "mcfio_Direct.h"
+#include "mcfio_Sequential.h"
+#include "mcf_NTuIOFiles.h"
+#include "mcf_NTuIOUtils.h"
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef MAP_FILE 
+#define MAP_FILE 0
+#endif
+
+extern nTuDDL **NTuDDLList;
+extern int NumOfNTuples;
+
+
+/* Static routine used in this module */
+
+static int mcfioC_gofornextevent(mcfStream *str);   
+static int  mcfioC_nextspecevt(mcfStream *str, int inum, int istore, 
+                                       int irun, int itrig); 
+static int openReadDirect(char*filename, int mode);
+
+
+int mcfioC_OpenReadDirect(char *filename)
+{                                            
+/*
+** Routine to open and read the header file for a Direct access Stream, 
+** Standard Unix I/O 
+*/
+    return openReadDirect(filename, MCFIO_DIRECT);
+}
+
+int mcfioC_OpenReadMapped(char *filename)
+{                                            
+/*
+** Routine to open and read the header file for a Direct access Stream, 
+** Standard Unix I/O 
+*/
+    return openReadDirect(filename, MCFIO_MEMMAPPED);
+}
+
+static int openReadDirect(char *filename, int mode)
+/*
+** Routine to open and read the header file for a Direct access Stream.
+*/
+{
+   int i, j, jstr, idtmp, ntot, ll1, jdRef, oldNumOfNTuples;
+   int iff;
+   u_int p1, p2;
+   FILE *ff;
+   mcfStream *str;
+   nTuDDL *ddl, *ddlRef;
+   struct stat statbuf;
+   char *srcFile;
+   
+   
+  if (McfStreamPtrList == NULL) mcfioC_Init(); 
+   
+  if (McfNumOfStreamActive >= MCF_STREAM_NUM_MAX) {
+     fprintf(stderr,
+  " mcfio_OpenReadDirect: Too many streams opened simultaneously.\n"); 
+     return -1;
+   }
+   jstr = -1; i=0;
+   while ((jstr == -1) && (i<MCF_STREAM_NUM_MAX)) {
+          if (McfStreamPtrList[i] == NULL) jstr=i;
+          i++;
+          }
+   if(jstr == -1) {
+     fprintf(stderr,
+  " mcfio_OpenReadDirect: Internal error, please report \n"); 
+     return -1;
+   }
+   if ((filename == NULL) || (strlen(filename) > 255)) {
+     fprintf(stderr,
+  " mcfio_OpenReadDirect: You must give a valid UNIX filename.\n"); 
+     return -1;
+   }
+   /*
+   ** Now we can try to open this file.... 
+   */
+   if (mode == MCFIO_DIRECT) {
+       ff = fopen(filename, "r");
+       if (ff == NULL) {
+           fprintf(stderr,
+    " mcfio_OpenReadDirect: Problem opening file %s, message \n", filename);
+           perror ("mcfio_OpenReadDirect"); 
+           return -1;
+       }
+   } else { 
+      /*
+      ** Using memory mapped i/o
+      */
+      iff = open(filename, O_RDONLY);
+          if (iff < 0) {
+          fprintf(stderr,
+  " mcfio_OpenReadMapped: Problem opening file %s, message \n", filename);
+          perror ("mcfio_OpenReadMapped"); 
+          return -1;
+      }
+   }
+   McfStreamPtrList[jstr] = (mcfStream *) malloc(sizeof(mcfStream));
+   str = McfStreamPtrList[jstr];
+   str->xdr = (XDR *) malloc(sizeof(XDR));
+   str->id = jstr+1;
+   str->row = MCFIO_READ;
+   str->dos = mode;
+   str->numWordsC = 0;
+   str->numWordsT = 0;
+   ll1 = strlen(filename) + 1;
+   str->filename = (char *) malloc(sizeof(char) * ll1);
+   strcpy(str->filename,filename);
+   if (mode == MCFIO_DIRECT) {
+       str->filePtr = ff;
+       xdrstdio_create(str->xdr, ff, XDR_DECODE);
+       str->fileDescr = 0;
+       str->fileAddr = NULL;
+       str->fileLen = 0; 
+   } else {
+      /*
+      ** Use memory mapped I/O 
+      */
+      if (fstat(iff, &statbuf) < 0) {
+          fprintf (stderr,
+  " mcfio_OpenReadMapped: Problem getting file length for %s \n", filename);
+          perror ("mcfio_OpenReadMapped"); 
+          return -1;
+      }
+      if ((srcFile =
+        mmap(0, statbuf.st_size, PROT_READ, MAP_FILE | MAP_SHARED, iff, 0 )) 
+        == (caddr_t) -1) {
+       fprintf (stderr,
+  " mcfio_OpenReadMapped: Problem with memory mapping for %s \n", filename);
+       perror ("mcfio_OpenReadMapped"); 
+       return -1;
+      }
+      str->filePtr = (FILE *) NULL;
+      str->fileDescr = iff;
+      str->fileAddr = srcFile;
+      str->fileLen = (size_t) statbuf.st_size;
+      xdrmem_create(str->xdr, srcFile, statbuf.st_size,  XDR_DECODE);          
+   }         
+   str->device = NULL;
+   str->vsn = NULL;
+   str->filenumber = -1;
+   str->minlrec = -1;
+   str->maxlrec = -1;
+   str->shead = NULL;
+   str->ehead = NULL;
+   str->table = NULL;
+   str->buffer = NULL;
+   str->buffer2 = NULL;
+   p1 = xdr_getpos(str->xdr);
+   str->firstPos = p1;
+   str->status = MCFIO_BOF;
+   str->fhead = NULL;
+   oldNumOfNTuples = NumOfNTuples;
+   if (xdr_mcfast_fileheader(str->xdr, &idtmp,
+                &ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
+       fprintf (stderr, 
+               "mcfio_OpenReadDirect: Unable to decode fileheader \n");
+       mcfioC_FreeStream(&McfStreamPtrList[jstr]);
+       mcfioC_Close(jstr+1);
+       return -1;
+   }
+   if (idtmp != FILEHEADER) {
+       fprintf (stderr, 
+            "mcfio_OpenReadDirect: First Structure not the header \n");
+      
+       fprintf (stderr, 
+            "                    : Further accesses probably suspicious \n");
+       mcfioC_FreeStream(&McfStreamPtrList[jstr]);
+       mcfioC_Close(jstr+1);
+       return -1;
+   }    
+   p2 = xdr_getpos(str->xdr);
+   str->numWordsC += (ntot/4);
+   /*
+   ** Check if new these Ntuple template are not reference, if so,
+   ** set the reference pointer accordingly, conversely, recompute the 
+   ** offsets and length if requested.  We also fill the sequential 
+   ** id number for the descriptors.  Note: those are trivial for 
+   ** input streams, but we still fill them for consitency.
+   */
+   for (i=0; i<str->fhead->nNTuples; i++) {
+      ddl = mcf_GetNTuByPtrID((oldNumOfNTuples+i+1));
+      if (ddl == NULL) continue;
+      ddl->streamId = (jstr+1);
+      ddl->seqNTuId = (i+1);
+      if (ddl->descrNtu == NULL) {
+          for (j=0, jdRef=1; j<i; j++, jdRef++) {
+             if (jdRef == ddl->referenceId) { 
+               ddlRef = mcf_GetNTuByPtrID((oldNumOfNTuples+j+1));
+               /*
+               ** back up in the linked list if need be, until we 
+                ** a fully documented descriptor.
+                */
+               while (ddlRef->descrNtu == NULL) ddlRef = ddlRef->reference;
+                 ddl->reference = ddlRef;
+                      break;
+             }
+        }
+      } else {
+          if (McfNTuPleSaveDecoding == TRUE) {
+             mcf_ComputeNTuOffsets(ddl);    
+             mcf_ComputeNTuLengths(ddl);
+          }   
+      }           
+   }
+   str->currentPos = p2;
+   str->fhead->firstTable = p2;
+    /* presumably correct , assume standard direct acces file config. */
+   str->numWordsT += ((p2-p1)/4);
+   str->status = MCFIO_RUNNING;
+   str->table = (mcfxdrEventTable *) malloc(sizeof(mcfxdrEventTable));
+   str->table->nextLocator = -1;
+   str->table->dim = str->fhead->dimTable;
+   str->table->numevts = 0;
+   str->table->previousnumevts = 0;
+   str->table->evtnums = NULL;
+   str->table->storenums = NULL;
+   str->table->runnums = NULL;
+   str->table->trigMasks = NULL;
+   str->table->ptrEvents = NULL;
+   str->ehead = (mcfxdrEventHeader *) malloc(sizeof(mcfxdrEventHeader));
+   str->ehead->dimBlocks = str->fhead->nBlocks;
+   str->ehead->blockIds = NULL;
+   str->ehead->ptrBlocks = NULL;
+   str->ehead->dimNTuples = str->fhead->nNTuples;
+   str->ehead->nTupleIds = NULL;
+   str->ehead->ptrNTuples = NULL;
+   McfNumOfStreamActive++;
+   return (jstr+1);
+}
+    
+int mcfioC_OpenWriteDirect(char *filename, char *title, char *comment,
+                           int numevts_pred, int *blkIds, u_int nBlocks)
+
+/*
+** Routine to open and write the header file for a Direct access Stream.
+*/
+{
+   int i, jstr;
+   u_int p1;
+   FILE *ff;
+   mcfStream *str;
+   
+  if (McfStreamPtrList == NULL) { 
+     fprintf(stderr,
+  " mcfio_OpenWriteDirect: We will first initialize by calling mcfio_Init.\n"); 
+     mcfioC_Init();
+  }
+  if (McfNumOfStreamActive >= MCF_STREAM_NUM_MAX) {
+     fprintf(stderr,
+  " mcfio_OpenWriteDirect: Too many streams opened simultaneously.\n"); 
+     return -1;
+   }
+   jstr = -1; i=0;
+   while ((jstr == -1) && (i<MCF_STREAM_NUM_MAX)) {
+          if (McfStreamPtrList[i] == NULL) jstr=i;
+          i++;
+          }
+   if(jstr == -1) {
+     fprintf(stderr,
+  " mcfio_OpenWriteDirect: Internal error, please report \n"); 
+     return -1;
+   }
+   if ((filename == NULL) || (strlen(filename) > 255)) {
+     fprintf(stderr,
+  " mcfio_OpenWriteDirect: You must give a valid UNIX filename.\n"); 
+     return -1;
+   }
+   if ((title != NULL) && (strlen(title) > 255)) {
+     fprintf(stderr,
+  " mcfio_OpenWriteDirect: Title is too long\n"); 
+     return -1;
+   }
+     
+   if ((comment != NULL) && (strlen(comment) > 255)) {
+     fprintf(stderr,
+  " mcfio_OpenWriteDirect: comment is too long\n"); 
+     return -1;
+   }
+      
+   /*
+   ** Now we can try to open this file.... 
+   */
+   ff = fopen(filename, "w");
+   if (ff == NULL) {
+     fprintf(stderr,
+  " mcfio_OpenWriteDirect: Problem opening file %s, message \n", filename);
+     perror ("mcfio_OpenWriteDirect"); 
+     return -1;
+   }
+   McfStreamPtrList[jstr] = (mcfStream *) malloc(sizeof(mcfStream));
+   str = McfStreamPtrList[jstr];
+   str->xdr = (XDR *) malloc(sizeof(XDR));
+   str->id = jstr+1;
+   str->row = MCFIO_WRITE;
+   str->dos = MCFIO_DIRECT;
+   str->numWordsC = 0;
+   str->numWordsT = 0;
+   str->filename = (char *) malloc(sizeof(char) * ( strlen(filename) +1) );
+   strcpy(str->filename,filename); 
+   str->filePtr = ff;
+   str->device = NULL;
+   str->vsn = NULL;
+   str->filenumber = -1;
+   str->minlrec = -1;
+   str->maxlrec = -1;
+   str->shead = NULL;
+   str->ehead = NULL;
+   str->table = NULL;
+   str->buffer = NULL;
+   str->buffer2 = NULL;
+   xdrstdio_create(str->xdr, ff, XDR_ENCODE);
+   p1 = xdr_getpos(str->xdr);
+   str->firstPos = p1;
+   str->currentPos = p1;
+   str->status = MCFIO_BOF;
+   str->fhead = (mcfxdrFileHeader *) malloc(sizeof(mcfxdrFileHeader));
+   /*
+   ** Fill the file header, additional info will be written on tape
+   */
+   if (title == NULL) strcpy(str->fhead->title,"No Title given");
+    else strcpy(str->fhead->title,title);
+    
+   if (comment == NULL) strcpy(str->fhead->comment,"No comment");
+    else strcpy(str->fhead->comment, comment);
+   str->fhead->numevts_expect = numevts_pred;
+   str->fhead->numevts = 0;
+   /* 
+   ** Futur expansion : make this a tunable parameter.
+   */
+   str->fhead->dimTable = MCF_DEFAULT_TABLE_SIZE;
+   str->fhead->firstTable = -1;
+   str->fhead->nBlocks = nBlocks;
+   if (nBlocks > 0) {
+      str->fhead->blockIds = (int *) malloc(sizeof(int) * nBlocks);
+      str->fhead->blockNames = (char**) malloc(sizeof(char *) * nBlocks);
+   } else {
+      str->fhead->blockIds = NULL;
+      str->fhead->blockNames = NULL;
+   }     
+   for (i=0; i<nBlocks; i++) {
+     str->fhead->blockIds[i] = blkIds[i];
+     str->fhead->blockNames[i] = 
+     (char *) malloc(sizeof(char) * (MCF_XDR_B_TITLE_LENGTH + 1));
+     mcfioC_GetBlockName(blkIds[i], str->fhead->blockNames[i]);
+   }
+   str->fhead->nNTuples = 0; /* Will be filled later */ 
+   if (mcfioC_Wrtfhead(str, INITIATE) == FALSE){
+       mcfioC_FreeStream(&McfStreamPtrList[jstr]);
+       fclose(ff);
+       return -1;
+   }
+   str->table = (mcfxdrEventTable *) malloc(sizeof(mcfxdrEventTable));
+   str->table->numevts=-1;
+   str->table->nextLocator = -1;
+   str->table->evtnums =   (int *) malloc(sizeof(int) * str->fhead->dimTable);
+   str->table->storenums = (int *) malloc(sizeof(int) * str->fhead->dimTable);
+   str->table->runnums = (int *) malloc(sizeof(int) * str->fhead->dimTable);
+   str->table->trigMasks = (int *) malloc(sizeof(int) * str->fhead->dimTable);
+   str->table->ptrEvents = 
+         (u_int *) malloc(sizeof(int) * str->fhead->dimTable);
+   /*
+   ** Write the first dummy table 
+   */
+   if (mcfioC_Wrttable(str, INITIATE) == FALSE) return -1;
+   str->ehead = (mcfxdrEventHeader *) malloc(sizeof(mcfxdrEventHeader));
+   str->ehead->dimBlocks = str->fhead->nBlocks;
+   str->ehead->nBlocks = 0;
+   str->ehead->dimNTuples = 0;
+   str->ehead->nNTuples = 0;
+   str->ehead->evtnum = 0;
+   str->ehead->previousevtnum = 0;
+   str->ehead->storenum = 0;
+   str->ehead->runnum = 0;
+   str->ehead->trigMask = 0;
+   str->ehead->nTupleIds = NULL;
+   str->ehead->ptrNTuples = NULL;
+   if (nBlocks > 0) {
+      str->ehead->blockIds = 
+          (int *) malloc(sizeof(int) * str->fhead->nBlocks);
+      str->ehead->ptrBlocks =
+         (u_int *) malloc(sizeof(int) * str->fhead->nBlocks);
+   } else {
+       str->ehead->blockIds = NULL;
+       str->ehead->ptrBlocks = NULL; 
+   }       
+   /*
+   ** Write the first dummy event header
+   */
+   if (mcfioC_WrtEvt(str, INITIATE) == FALSE) return -1;
+   str->ehead->evtnum = 0;
+   str->status = MCFIO_RUNNING;
+   McfNumOfStreamActive++;
+   return (jstr+1);
+
+}
+
+int mcfioC_NextEvent(int stream)
+/*
+** The Core routine for getting or setting the next event d.s. from/to 
+**  a stream. 
+**
+*/
+{
+   int jstr, idtmp, ntot, nn1;
+   u_int p_evt, p2;
+   mcfStream *str;
+   
+  if (McfStreamPtrList == NULL) { 
+     fprintf(stderr,
+  " mcfio_NextEvent: You must first initialize by calling mcfio_Init.\n"); 
+     return -1;
+  }
+  jstr = stream-1;
+  if (McfStreamPtrList[jstr] == NULL) { 
+     fprintf(stderr,
+ " mcfio_NextEvent: First, declare the stream by calling mcfio_Open...\n"); 
+     return -1;
+  }
+  str = McfStreamPtrList[jstr];
+  if (str->dos == MCFIO_SEQUENTIAL) return mcfioC_NextEventSequential(stream);
+  if (str->row == MCFIO_READ) {
+  /*
+  ** Read the next event, hunt for either an event or a table of event
+  **  if event table not available.
+  */
+      if ((str->table == NULL) || 
+         ((str->table != NULL)&& (str->table->evtnums == NULL))) { 
+                idtmp = mcfioC_gofornextevent(str);
+                if (idtmp != EVENTTABLE) {
+                    if (str->table !=NULL) 
+                       mcfioC_Free_EventTable(&(str->table));
+                    if (idtmp == NOTHING) return -1;
+                    p_evt = str->currentPos;
+                 } else {
+                  if( xdr_mcfast_eventtable(str->xdr, &idtmp,
+ 		     &ntot, McfGenericVersion, &(str->table)) == FALSE) {
+                           fprintf(stderr,
+ " mcfio_NextEvent: XDR Error decoding the EventTable \n"); 
+ 		            return -1;
+ 		    }
+                    p2 = xdr_getpos(str->xdr);
+                    str->numWordsC += (ntot/4);
+                    str->numWordsT += ((p2-str->currentPos)/4);
+                    str->currentPos = p2;
+                    str->table->ievt = 0;
+                    /* 
+                    ** If table empty, cal this routine recursively to get 
+                    **   the next event 
+                    */
+                    if (str->table->numevts <= 0) {
+                      if (str->table->nextLocator == -1) 
+                       mcfioC_Free_EventTable(&(str->table));
+                       return mcfioC_NextEvent(str->id);
+                    }     
+                    p_evt = str->table->ptrEvents[0];
+                } 
+      } else {
+           if (str->table->ievt < str->table->numevts) {
+                 p_evt = str->table->ptrEvents[str->table->ievt];
+           } else {
+           /*
+           ** decode the next table, if valid. If not, scrap the 
+           ** existing table and call next event recursively.
+           */
+              if (str->table->nextLocator == -2) {
+                  /* 
+                  ** Stream is at EOF
+                  */
+                   str->status = MCFIO_EOF;
+                   return MCFIO_EOF;
+              } else if (str->table->nextLocator == -1) { 
+                           fprintf(stderr,
+ " mcfio_NextEvent: Corrupted Event Table \n"); 
+ 		            return -1;
+                }
+                if (xdr_setpos(str->xdr, str->table->nextLocator) == FALSE) {
+                           fprintf(stderr,
+ " mcfio_NextEvent: Error Repositioning stream \n"); 
+ 		            return -1;
+ 		 }
+                 if( xdr_mcfast_eventtable(str->xdr, &idtmp,
+ 		     &ntot, McfGenericVersion, &(str->table)) == FALSE) {
+                           fprintf(stderr,
+ " mcfio_NextEvent: XDR Error decoding the EventTable \n"); 
+ 		            return -1;
+ 		    }
+                    p2 = xdr_getpos(str->xdr);
+                    str->numWordsC += (ntot/4);
+                    str->numWordsT += ((p2-str->currentPos)/4);
+                    str->currentPos = p2;
+                    str->table->ievt = 0;
+                    p_evt = str->table->ptrEvents[0];
+                  }
+       }
+       /* 
+       ** we should be pointing to a good event header here. 
+       */
+       if (xdr_setpos(str->xdr, p_evt) == FALSE) return -1;
+       if( xdr_mcfast_eventheader(str->xdr, &idtmp,
+	&ntot, McfGenericVersion, &(str->ehead)) == FALSE) return -1;
+        str->currentPos = xdr_getpos(str->xdr);
+        str->numWordsC += (ntot/4);
+        str->numWordsT += ((str->currentPos - p_evt)/4);
+        if (str->table != NULL) str->table->ievt ++;              
+        return MCFIO_RUNNING;
+  } else {
+    /*
+    ** Writing Code here.
+    */
+    str->table->numevts++;
+    str->fhead->numevts++;
+    if (str->ehead->previousevtnum == str->ehead->evtnum) str->ehead->evtnum++;
+     /*
+     ** Write the current event header, normal case. First Flush the current
+     **  event,  then initiate the next one event. Note that wrtevt will
+     ** reposition the stream after rewriting the event header, if FLUSH. 
+     ** e.g. ready to initiate either a new table or a new event.
+     */
+     if (mcfioC_WrtEvt(str, FLUSH) == FALSE) return -1;
+     str->ehead->previousevtnum = str->ehead->evtnum;
+     if (str->table->numevts == (str->fhead->dimTable - 1)) {
+      /*
+      ** The Event table is now full. Flush it. Then initiate a new table. 
+      */ 
+       str->table->nextLocator = xdr_getpos(str->xdr);
+       if (mcfioC_Wrttable(str, FLUSH) == FALSE) return -1;
+       if (mcfioC_Wrttable(str, INITIATE) == FALSE) return -1;
+     }
+     str->ehead->nBlocks = 0;
+     str->ehead->nNTuples = 0;
+     nn1 = str->ehead->evtnum;
+     if (mcfioC_WrtEvt(str, INITIATE) == FALSE) return -1;
+     str->ehead->evtnum = nn1;
+     return MCFIO_RUNNING;
+  }
+}
+
+int mcfioC_SpecificEvent(int stream, int ievt,
+                             int istore, int irun, int itrig)
+{
+   int jstr, ok;
+   mcfStream *str;
+   
+  if (McfStreamPtrList == NULL) { 
+     fprintf(stderr,
+  " mcfio_SpecificEvent: You must first initialize by calling mcfio_Init.\n"); 
+     return -1;
+  }
+  jstr = stream-1;
+  if (McfStreamPtrList[jstr] == NULL) { 
+     fprintf(stderr,
+ " mcfio_SpecificEvent: First, declare the stream by calling mcfio_Open...\n"); 
+     return -1;
+  }
+  str = McfStreamPtrList[jstr];
+  if ((str->row != MCFIO_READ) || (str->dos == MCFIO_SEQUENTIAL)) {
+     fprintf(stderr,
+" mcfio_SpecificEvent: Only valid for INPUT, DIRECT ACCESS \
+ or Memory Mapped \n"); 
+     return -1;
+     }
+  if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE ) {
+       fprintf(stderr,
+ " mcfio_SpecificEvent:  Could not reposition Direct Access Stream %d \n",
+         (jstr+1)) ;
+    return -1;
+   }
+   str->currentPos = str->fhead->firstTable;
+   
+   ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
+   if (ok == FALSE) {
+      mcfioC_RewindDirect(jstr);
+      if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE ) {
+           fprintf(stderr,
+     " mcfio_SpecificEvent:  Could not reposition Direct Access Stream %d \n",
+         (jstr+1)) ;
+         return -1;
+      }
+      str->currentPos = str->fhead->firstTable;
+      ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
+    }
+    if (ok == FALSE)   return -1;
+   return ok;
+    
+}	                             
+int mcfioC_NextSpecificEvent(int stream, int ievt,
+                             int istore, int irun, int itrig)
+{
+   int jstr, ok;
+   mcfStream *str;
+   
+  if (McfStreamPtrList == NULL) { 
+     fprintf(stderr,
+  " mcfio_NextSpecific: You must first initialize by calling mcfio_Init.\n"); 
+     return -1;
+  }
+  jstr = stream-1;
+  if (McfStreamPtrList[jstr] == NULL) { 
+     fprintf(stderr,
+ " mcfio_NextSpecific: First, declare the stream by calling mcfio_Open...\n"); 
+     return -1;
+  }
+  str = McfStreamPtrList[jstr];
+  if ((str->row != MCFIO_READ) || (str->dos == MCFIO_SEQUENTIAL)) {
+     fprintf(stderr,
+ " mcfio_NextSpecificEvent: Only valid for INPUT, DIRECT ACCESS\
+ or memory mapped I/O  \n"); 
+     return -1;
+     }
+   ok = mcfioC_nextspecevt(str, ievt, istore, irun, itrig);
+   if (ok == FALSE) return -1;
+   return ok;
+    
+}	                             
+
+
+void mcfioC_CloseDirect(int jstr)
+/*
+** Close a direct access stream, Standard I/O or Memory Mapped
+**
+*/
+{
+   int i;
+   mcfStream *str;
+   nTuDDL *ddl;
+      
+   str =  McfStreamPtrList[jstr];
+   if (str->row == MCFIO_WRITE) {
+       /*
+       **  Flush the event header, and the last table header. 
+       */
+       if (str->status == MCFIO_RUNNING) { 
+         str->table->numevts++;
+         str->ehead->evtnum++;
+         if (mcfioC_WrtEvt(str, FLUSH) == FALSE) return;
+         str->table->nextLocator = -2;
+         str->table->numevts--; /* Decrement, the table is incomplete at 
+         				this point */
+         if (mcfioC_Wrttable(str, FLUSH) == FALSE) return;
+         if (mcfioC_Wrtfhead(str, FLUSH) == FALSE) return;
+       }
+     }
+     xdr_destroy(str->xdr);
+     if (str->dos == MCFIO_DIRECT) { 
+         fclose(str->filePtr);
+     } else {
+         /*
+         ** Memory mapped I/O, one has to unmapped.. 
+         */
+         munmap((caddr_t) str->fileAddr, str->fileLen);
+         close(str->fileDescr);
+     }
+     /*
+     ** One must declare the Ntuples obsolete for this stream. 
+     ** Do not release the memory, just flag these Ntuple with an obsolete 
+     ** stream
+     */
+     for (i=0; i<NumOfNTuples; i++) {
+         ddl = mcf_GetNTuByPtrID((i+1));
+         if ((ddl != NULL) && (ddl->streamId == (jstr+1)))
+               ddl->streamId = -1;
+    }
+}
+       
+void mcfioC_RewindDirect(int jstr)
+/*
+** Rewind a direct access stream, open for Read only
+**
+*/
+{
+    mcfStream *str;
+    
+    str =  McfStreamPtrList[jstr];
+    if (xdr_setpos(str->xdr, str->fhead->firstTable) == FALSE )
+       fprintf(stderr,
+       " mcfio_Rewind:  Could not reposition Direct Access Stream %d \n",
+         (jstr+1)) ;
+    str->currentPos = str->fhead->firstTable;
+    if (str->table != NULL) {
+        str->table->nextLocator = str->fhead->firstTable;
+        str->table->numevts = 0;
+        str->table->previousnumevts = 0;
+    }    
+    if (str->ehead != NULL) {
+        str->ehead->evtnum = 0;
+        str->ehead->previousevtnum = 0;
+    }
+    return;
+}  
+   
+int  mcfioC_Wrtfhead(mcfStream *str, int mode)     
+/*
+** Write the file header. 
+**  IF Mode = INITIATE, write the dummy information, at the current location.
+**  IF mode = Flush, rewite all the information, this time with the 
+**  correct number of events.
+**
+*/
+{
+   int idtmp, ntot;
+   u_int p1, p0;
+   int k;
+    time_t clock;
+   
+   idtmp = FILEHEADER;
+   if (mode == FLUSH) {
+     time(&clock);
+     strcpy(str->fhead->closingDate, ctime(&clock));
+     if(xdr_setpos(str->xdr,str->firstPos) == FALSE) return FALSE; 
+     if (xdr_mcfast_fileheader(str->xdr, &idtmp,
+          &ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
+       fprintf (stderr, 
+               "mcfio_OpenCloseDirect: Unable to reencode file head \n");
+       return FALSE;
+      }
+      /*
+      ** The version of MCFIO is still at this point v2.0 
+      */
+   } else if (mode == INITIATE) {
+       /* Put the current date/time in a string */
+     time(&clock);
+     strcpy(str->fhead->date, ctime(&clock));
+     /*
+     ** We obviously do not have the closing times stamp yet (Causality)
+     ** So we put ?, however, we have to put the right number of them, 
+     ** the we do not screw up the XDR pointers..
+     */
+     for (k=0; k<strlen(ctime(&clock)); k++) str->fhead->closingDate[k] = '?';
+     str->fhead->closingDate[strlen(ctime(&clock))] = '\0';
+     p0 = str->currentPos;
+     if (xdr_mcfast_fileheader(str->xdr, &idtmp,
+               &ntot, McfGenericVersion, &(str->fhead), str->id) == FALSE) {
+       fprintf (stderr, 
+               "mcfio_OpenWriteDirect: Unable to encode fileheader \n");
+       return FALSE;
+      } 
+      p1 = xdr_getpos(str->xdr);
+      str->numWordsC += (ntot/4);
+      str->numWordsT += ((p1-p0)/4);
+      str->currentPos = p1;
+      return TRUE;
+   } else {
+     fprintf(stderr," mcfioC_Wrtfhead: Internal error, lost mode \n");
+     return FALSE;
+   }
+   return TRUE;
+}
+             
+   
+int  mcfioC_WrtEvt(mcfStream *str, int mode)     
+/*
+** Write an event header, and update the table. Presumably, we have room 
+**  in this table to do so.
+**  IF Mode = INITIATE, write the dummy event header, at the current location.
+**   Do not fill the element table.
+**  If mode = FLUSH write the real event header and also
+**     fill the Table elements. 
+**
+*/
+{
+   int idtmp, ntot;
+   u_int p1, p0;
+   
+   idtmp = EVENTHEADER;
+   if (mode == FLUSH) {
+    str->table->evtnums[str->table->numevts] = str->ehead->evtnum;             
+    str->table->storenums[str->table->numevts] = str->ehead->storenum;             
+    str->table->runnums[str->table->numevts] = str->ehead->runnum;             
+    str->table->trigMasks[str->table->numevts] = str->ehead->trigMask;
+    str->table->ptrEvents[str->table->numevts] = str->evtPos;
+    p0 = str->currentPos;
+    if(xdr_setpos(str->xdr,str->evtPos) == FALSE) return FALSE; 
+    p1 = str->evtPos;
+    if(xdr_mcfast_eventheader(str->xdr, &idtmp,
+            &ntot, McfGenericVersion, &(str->ehead)) == FALSE) return FALSE;
+    str->currentPos = xdr_getpos(str->xdr); 
+    str->numWordsC += (ntot/4);
+    str->numWordsT += ((str->currentPos-p1)/4);
+    if(xdr_setpos(str->xdr,p0) == FALSE) return FALSE;
+    str->currentPos = p0;
+    str->ehead->nBlocks = 0;
+    str->ehead->nNTuples = 0;
+    return TRUE;
+   } else if (mode == INITIATE) {
+    str->ehead->nBlocks = 0; /*do not initialize nNTuples, already done */
+    str->ehead->evtnum = -1;
+    str->evtPos = xdr_getpos(str->xdr);
+    
+    if(xdr_mcfast_eventheader(str->xdr, &idtmp,
+            &ntot, McfGenericVersion, &(str->ehead)) == FALSE) return FALSE;
+    str->currentPos = xdr_getpos(str->xdr);
+    return TRUE;
+   } else {
+     fprintf(stderr," mcfioC_WrtEvt: Internal error, lost mode \n");
+     return FALSE;
+   }
+}
+             
+int  mcfioC_Wrttable(mcfStream *str, int mode)     
+/*
+** Write an event table. 
+**  IF Mode = INITIATE, write the dummy event table, at the current location.
+**   Do not fill the element table.
+**  If mode = FLUSH write the real event header and also
+**     fill the Table elements. 
+**
+*/
+{
+   int idtmp, ntot;
+   u_int p1, p0;
+   
+   idtmp = EVENTTABLE;
+   str->table->dim = str->fhead->dimTable;
+   if (mode == FLUSH) {
+    p0 = str->currentPos;
+    if(xdr_setpos(str->xdr,str->tablePos) == FALSE) return FALSE; 
+    p1 = str->tablePos;
+    str->table->numevts++;
+    if(xdr_mcfast_eventtable(str->xdr, &idtmp,
+            &ntot, McfGenericVersion, &(str->table)) == FALSE) return FALSE;
+    str->currentPos = xdr_getpos(str->xdr); 
+    str->numWordsC += (ntot/4);
+    str->numWordsT += ((str->currentPos-p1)/4);
+    if(xdr_setpos(str->xdr,p0) == FALSE) return FALSE;
+    str->currentPos = p0;
+    str->tablePos = -1;
+    str->table->nextLocator = -1;
+    str->table->numevts=-1;
+    return TRUE;
+   } else if (mode == INITIATE) {
+    str->tablePos = xdr_getpos(str->xdr);
+    str->table->nextLocator = -1;
+    if(xdr_mcfast_eventtable(str->xdr, &idtmp,
+            &ntot, McfGenericVersion, &(str->table)) == FALSE) return FALSE;
+    str->currentPos = xdr_getpos(str->xdr);
+    return TRUE;
+   } else {
+     fprintf(stderr," mcfioC_Wrttable: Internal error, lost mode \n");
+     return FALSE;
+   }
+}
+
+static int mcfioC_gofornextevent(mcfStream *str)   
+/*
+** Move in the direct access file to the next event or event table, 
+** whatever comes first. The XDR current position is set to the beginning 
+** of the event header or event table, if search sucessfull.
+** We position the stream to the last Block or Ntuple defined in 
+** the current event. 
+*/
+{
+   u_int p1;
+   int id, ntot, go;
+   
+   go = TRUE;
+   
+   while (go == TRUE) {
+     p1 = xdr_getpos(str->xdr);
+     if (xdr_mcfast_headerBlock(str->xdr, &id, &ntot, McfGenericVersion)
+            == FALSE)  return NOTHING;
+     if ((id == EVENTTABLE) || (id == EVENTHEADER)) {
+         str->currentPos = p1;
+         if(xdr_setpos(str->xdr, p1) == FALSE) return NOTHING;
+         return id;
+     }
+   }
+   return NOTHING; /* This statement is to make the compiler happy */
+}  
+             
+static int  mcfioC_nextspecevt(mcfStream *str, int inum, int istore, 
+                                       int irun, int itrig)
+/*
+** For Input, Direct access streams, hunt for a psecific event
+**
+*/  
+{
+   int j, idtmp, ntot, found;
+   u_int p_evt, p2;
+   
+   if ((str->table == NULL) || 
+         ((str->table != NULL)&& (str->table->evtnums == NULL))) { 
+                idtmp = mcfioC_gofornextevent(str);
+                if (idtmp != EVENTTABLE) {
+                  fprintf(stderr,
+ " mcfio_SpecificEvent: No event table on stream %d \n", str->id);
+                  return FALSE;
+                 } else {
+                  if( xdr_mcfast_eventtable(str->xdr, &idtmp,
+ 		     &ntot, McfGenericVersion, &(str->table)) == FALSE) {
+                           fprintf(stderr,
+ " mcfio_SpecificEvent: XDR Error decoding the EventTable \n"); 
+ 		            return FALSE;
+ 		    }
+                    p2 = xdr_getpos(str->xdr);
+                    str->numWordsC += (ntot/4);
+                    str->numWordsT += ((p2-str->currentPos)/4);
+                    str->currentPos = p2;
+                    str->table->ievt = 0;
+                    /* 
+                    ** If table empty, cal this routine recursively to get 
+                    **   the next event 
+                    */
+                    str->table->ievt = 0;
+                } 
+      }
+      found = FALSE;
+      while (found == FALSE){
+           j =  str->table->ievt;    
+           if (str->table->ievt < str->table->numevts) {
+             if (((inum == 0)
+                 || ( inum != 0 && (str->table->evtnums[j] == inum))) &&
+                 (((istore == 0) 
+                 || (istore != 0) && (str->table->storenums[j] == istore))) &&
+                 (((irun == 0) 
+                 || (irun != 0) && (str->table->runnums[j] == irun))) &&
+                 (((itrig == 0) 
+                 || (itrig != 0) && (str->table->trigMasks[j] == itrig))))
+                  found = TRUE;
+                  p_evt = str->table->ptrEvents[str->table->ievt];
+                  str->table->ievt++;
+           } else {
+           /*
+           ** decode the next table, if valid. If not, scrap the 
+           ** existing table and call next event recursively.
+           */
+              if (str->table->nextLocator == -2) {
+                  /* 
+                  ** Stream is at EOF
+                  */
+                   str->status = MCFIO_EOF;
+		   
+                   return FALSE;
+		   
+              } else  if (str->table->nextLocator == -1) {
+                           fprintf(stderr,
+ " mcfio_NextEvent: Next EventTable corrupted, abandoning search \n"); 
+ 		            return FALSE;
+              }
+              if (xdr_setpos(str->xdr, str->table->nextLocator)
+                      == FALSE) { fprintf(stderr,
+ " mcfio_NextEvent: XDR Error repositioning to the next EventTable \n"); 
+ 		            return FALSE;
+              } else  {
+                     if( xdr_mcfast_eventtable(str->xdr, &idtmp,
+ 		     &ntot, McfGenericVersion, &(str->table)) == FALSE) {
+                           fprintf(stderr,
+ " mcfio_NextEvent: XDR Error decoding the EventTable \n"); 
+ 		            return FALSE;
+ 		    }
+ 	       }
+               p2 = xdr_getpos(str->xdr);
+               str->numWordsC += (ntot/4);
+               str->numWordsT += ((p2-str->currentPos)/4);
+               str->currentPos = p2;
+               str->table->ievt = 0;
+               p_evt = str->table->ptrEvents[0];
+           }
+       }
+       if (found == FALSE) return FALSE;
+       /* 
+       ** we should be pointing to a good event header here. 
+       */
+       if (xdr_setpos(str->xdr, p_evt) == FALSE) return FALSE;
+       if( xdr_mcfast_eventheader(str->xdr, &idtmp,
+	&ntot, McfGenericVersion, &(str->ehead)) == FALSE) return FALSE;
+        str->currentPos = xdr_getpos(str->xdr);
+        str->numWordsC += (ntot/4);
+        str->numWordsT += ((str->currentPos - p_evt)/4);
+        return MCFIO_RUNNING;
+        
+}
Index: /trunk/Utilities/mcfio/mcfio_Direct.h
===================================================================
--- /trunk/Utilities/mcfio/mcfio_Direct.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_Direct.h	(revision 3)
@@ -0,0 +1,24 @@
+/*******************************************************************************
+*									       *
+* mcfio_Direct.h --  Include file for mcfast Direct i/o layer. 		       *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+*									       *
+*******************************************************************************/
+#define INITIATE 3
+#define FLUSH 4
+int mcfioC_OpenReadDirect(char *filename);
+int mcfioC_OpenReadMapped(char *filename);
+int mcfioC_OpenWriteDirect(char *filename, char *title, char *comment, 
+                           int numevts_pred, int *blkIds, u_int nBlocks);
+int mcfioC_NextEvent(int stream);
+int mcfioC_SpecificEvent(int stream, int ievt,
+                             int istore, int irun, int itrig);
+int mcfioC_NextSpecificEvent(int stream, int ievt,
+                             int istore, int irun, int itrig);
+void mcfioC_CloseDirect(int jstr);
+void mcfioC_RewindDirect(int jstr);
+int  mcfioC_WrtEvt(mcfStream *str, int mode);    
+int  mcfioC_Wrttable(mcfStream *str, int mode);     
+int  mcfioC_Wrtfhead(mcfStream *str, int mode);
Index: /trunk/Utilities/mcfio/mcfio_SeqDummy.c
===================================================================
--- /trunk/Utilities/mcfio/mcfio_SeqDummy.c	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_SeqDummy.c	(revision 3)
@@ -0,0 +1,65 @@
+/*******************************************************************************
+*									       *
+* mcfio_SeqDummy.c --  Utility routines for the McFast Monte-Carlo               *
+*	Dummy Sequential routines, for the library without Sequential          *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Paul Lebrun						       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include "mcfio_Sequential.h"
+
+int mcfioC_OpenReadSequential(char *device, char *label, int filenumber)
+{
+	fprintf(stderr,
+	"mcfioC_OpenReadSequential: Not available in this library. \n");
+	return -1;
+}
+
+
+int mcfioC_OpenWriteSequential(char *device, char *label, char *title,
+             char *comment, int numevts_pred,
+              int *blkIds, unsigned int nBlocks)
+{
+	fprintf(stderr,
+	"mcfioC_OpenWriteSequential: Not available in this library. \n");
+	return -1;
+}
+
+int mcfioC_NextEventSequential(int stream)
+{
+	fprintf(stderr,
+	"mcfioC_NextEventSequential: Not available in this library. \n");
+	return -1;
+}
+
+void mcfioC_CloseSequentialFile(int jstr)
+{
+	fprintf(stderr,
+	"mcfioC_CloseSequentialFile: Not available in this library. \n");
+	return;
+}
+
+void mcfioC_CloseSequentialTape(int jstr)
+{
+	fprintf(stderr,
+	"mcfioC_CloseSequentialTape: Not available in this library. \n");
+	return;
+}
Index: /trunk/Utilities/mcfio/mcfio_Sequential.h
===================================================================
--- /trunk/Utilities/mcfio/mcfio_Sequential.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_Sequential.h	(revision 3)
@@ -0,0 +1,15 @@
+/*******************************************************************************
+*									       *
+* mc_Sequential.h --  Include file for mcfast Sequential i/o layer.            *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+*									       *
+*******************************************************************************/
+int mcfioC_OpenReadSequential(char *device, char *label, int filenumber);
+int mcfioC_OpenWriteSequential(char *device, char *label, char *title, 
+                char *comment, int numevts_pred, 
+                int *blkIds, unsigned int nBlocks);
+int mcfioC_NextEventSequential(int stream);
+void mcfioC_CloseSequentialFile(int stream);
+void mcfioC_CloseSequentialTape(int stream);
Index: /trunk/Utilities/mcfio/mcfio_UserDictionary.c
===================================================================
--- /trunk/Utilities/mcfio/mcfio_UserDictionary.c	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_UserDictionary.c	(revision 3)
@@ -0,0 +1,57 @@
+/*
+** A small container to hold a set of user block declaration
+**
+* Written by Paul Lebrun, Aug 2001
+*/
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <rpc/xdr.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "mcfio_UserDictionary.h"
+
+#define NUMUSERBLOCKDEFAULT 100
+
+allMCFIO_UserBlockDecl *AllMCFIO_UserBlockDecl = NULL;
+
+
+char *mcfioC_UserBlockDescript(int blkn)
+{
+   int i;
+   if (AllMCFIO_UserBlockDecl == NULL) return NULL;
+   for (i=0; i<AllMCFIO_UserBlockDecl->num; i++) {
+     if (AllMCFIO_UserBlockDecl->decls[i]->blkNum == blkn) 
+        return AllMCFIO_UserBlockDecl->decls[i]->title;
+   }
+   return NULL;
+}
+
+void mcfioC_DefineUserBlock(int blkN, char *descr){
+   aUserBlockDecl *abd;
+   
+   if (AllMCFIO_UserBlockDecl == NULL) {
+   
+      AllMCFIO_UserBlockDecl = (allMCFIO_UserBlockDecl *) malloc (
+                             sizeof(allMCFIO_UserBlockDecl));
+      AllMCFIO_UserBlockDecl->numPreAlloc = NUMUSERBLOCKDEFAULT;
+      AllMCFIO_UserBlockDecl->num = 0;
+      AllMCFIO_UserBlockDecl->decls = (aUserBlockDecl **) malloc( 
+                            NUMUSERBLOCKDEFAULT * sizeof(aUserBlockDecl *));
+   }
+   if (AllMCFIO_UserBlockDecl->num == AllMCFIO_UserBlockDecl->numPreAlloc) {
+       AllMCFIO_UserBlockDecl->numPreAlloc += NUMUSERBLOCKDEFAULT;
+       AllMCFIO_UserBlockDecl->decls = 
+	(aUserBlockDecl **) realloc (((void *) AllMCFIO_UserBlockDecl->decls), 
+	   (AllMCFIO_UserBlockDecl->numPreAlloc  * sizeof(aUserBlockDecl *)));
+   }
+   AllMCFIO_UserBlockDecl->decls[AllMCFIO_UserBlockDecl->num] = 
+     (aUserBlockDecl *) malloc (sizeof(aUserBlockDecl));
+   abd = AllMCFIO_UserBlockDecl->decls[AllMCFIO_UserBlockDecl->num];
+   AllMCFIO_UserBlockDecl->num++;
+   abd->blkNum = blkN;
+   abd->title = (char *) malloc (sizeof(char) * (strlen(descr) + 1));
+   strcpy(abd->title, descr);
+}    
Index: /trunk/Utilities/mcfio/mcfio_UserDictionary.h
===================================================================
--- /trunk/Utilities/mcfio/mcfio_UserDictionary.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_UserDictionary.h	(revision 3)
@@ -0,0 +1,25 @@
+/*
+** A small container to hold a set of user block declaration
+**
+* Written by Paul Lebrun, Aug 2001
+*/
+
+typedef struct _aUserBlockDecl {
+	int blkNum;
+	char *title;
+} aUserBlockDecl;
+
+typedef struct _allMCFIO_UserBlockDecl {
+	int num;
+	int numPreAlloc;
+	aUserBlockDecl **decls;
+}allMCFIO_UserBlockDecl ;
+
+extern allMCFIO_UserBlockDecl *AllMCFIO_UserBlockDecl;
+
+/*
+** Internally used in mcfio. Return NULL if not on the list, 
+** otherwise return the point to the relevant title block.
+*/
+char *mcfioC_UserBlockDescript(int blkNum);
+	
Index: /trunk/Utilities/mcfio/mcfio_Util1.c
===================================================================
--- /trunk/Utilities/mcfio/mcfio_Util1.c	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_Util1.c	(revision 3)
@@ -0,0 +1,910 @@
+/*******************************************************************************
+*									       *
+* mcfio_Init.c -- Utility routines for the McFast Monte-Carlo                    *
+*		Initialisation & info routines                                 *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Paul Lebrun						       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <rpc/xdr.h>
+#include <limits.h>
+#include <stdlib.h>
+#ifdef SUNOS
+#include <floatingpoint.h>
+#else /* SUNOS */
+#include <float.h>
+#endif /* SUNOS */
+#include <time.h>
+#include "mcf_nTupleDescript.h"
+#include "mcf_xdr.h"
+#include "mcfio_Util1.h"
+#include "mcfio_Direct.h"
+#include "mcfio_Sequential.h"
+#include "mcfio_Dict.h"
+#include "mcf_ntubld_db.h"
+#include "mcf_NTuIOFiles.h"
+#include "mcf_NTuIOUtils.h"
+#include "mcf_NTuIOUtils.h"
+#include "mcfio_UserDictionary.h"
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+mcfStream **McfStreamPtrList=NULL;
+unsigned int McfNumOfStreamActive=0;
+char **McfGenericVersion=NULL;
+
+/*
+** This stuff is needed for dbin utilities...
+*/
+struct line_title_c line_title_c_;
+struct header_c header_c_;
+struct variable_c variable_c_;
+/*
+** Names of variable types for Ntuple utilities
+*/ 
+char *VarTypesNamesF77[N_VAR_TYPES];
+char *VarTypesNamesC[N_VAR_TYPES];
+/*
+** Ntuple global list
+*/
+extern nTuDDL **NTuDDLList;
+extern int NumOfNTuples;
+
+
+void mcfioC_Init(void)
+/* Global Initialisation routine. Simply set the 
+**
+*/
+{
+  int i;
+
+/*
+** This is no longer needed... 
+
+    char *env, *line;
+    FILE *Ffp;  
+
+    env = NULL;
+    env = getenv("MCFIO_DIR");
+    if (env == NULL) { 
+       printf ("You must first set the environment variable MCFIO_DIR\n");
+       printf ("  by either setting up mcfio (Fermi UPS), or setting \n");
+       printf
+        ("  this env. variable to the place where mcf_NTuBld.db resides.\n");
+       exit(0);
+    } */
+    
+    
+    /*
+    ** Check now that the master template exist.
+    
+    line = (char *) malloc(sizeof(char) * (FILENAME_MAX+1));
+    sprintf(line,"%s/mcf_NTuBld.db", env);
+    Ffp = fopen(line, "r");
+    if (Ffp == NULL) {
+       printf ("The file %s could not be opened. \n", line);
+       printf (" Please check MCFIO installation. \n"); 
+       exit(0);
+    }
+    fclose(Ffp);
+    free(line);
+    
+*/
+  /*
+  ** Use only one version for now.  Possible extension here.
+  */
+  McfGenericVersion = (char **) malloc(sizeof(char *));
+  *McfGenericVersion = (char *) malloc(sizeof(char) * 8);
+  
+  VarTypesNamesF77[0]= "Byte         ";
+  VarTypesNamesF77[1]= "Character    ";
+  VarTypesNamesF77[2]= "Integer*2    ";
+  VarTypesNamesF77[3]= "Logical      ";
+  VarTypesNamesF77[4]= "Integer      ";
+  VarTypesNamesF77[5]= "Real         ";
+  VarTypesNamesF77[6]= "Double Precision";
+  VarTypesNamesF77[7]= "Complex      ";
+  VarTypesNamesF77[8]= "Double Complex  ";
+  VarTypesNamesF77[9]= "Pointer      ";
+        
+  VarTypesNamesC[0]= "char         ";
+  VarTypesNamesC[1]= "char         ";
+  VarTypesNamesC[2]= "short        ";
+  VarTypesNamesC[3]= "int          ";
+  VarTypesNamesC[4]= "int          ";
+  VarTypesNamesC[5]= "float        ";
+  VarTypesNamesC[6]= "double       ";
+  VarTypesNamesC[7]= "float[2]     ";
+  VarTypesNamesC[8]= "double[2]    ";
+  VarTypesNamesC[9]= "void *       ";
+  
+  if (NTuDDLList != NULL) {
+      for (i=0; i<NumOfNTuples; i++) DestroyNTuDDL(NTuDDLList[i]);
+      free(NTuDDLList);
+  }
+  NTuDDLList = (nTuDDL **) malloc(sizeof(int *)* NTU_START_LIST_SIZE);
+  NumOfNTuples = 0;
+  
+  if (McfStreamPtrList == NULL) {  
+	McfStreamPtrList = (mcfStream **)
+		 malloc(sizeof(mcfStream *) * MCF_STREAM_NUM_MAX);
+        for (i=0; i< MCF_STREAM_NUM_MAX; i++) McfStreamPtrList[i] = NULL;
+        return;
+   } 
+  for (i=0; i< MCF_STREAM_NUM_MAX; i++) McfStreamPtrList[i] = NULL;
+  mcfioC_Close(0); 
+  McfNumOfStreamActive=0;
+  
+}
+
+void mcfioC_Close(int istream) 
+/* 
+** Closing a Stream istream is the F77 index to the array of mcf Streams.
+*/
+{
+   int i;
+   
+   if (McfStreamPtrList == NULL) return;
+   if ((istream < 0) || (istream >  MCF_STREAM_NUM_MAX)) {
+      fprintf (stderr, "mcf_close, Illegal argument, stream = %d \n", istream);
+      return;
+   }   
+   if (istream == 0) {
+       for (i=0; i<MCF_STREAM_NUM_MAX; i++) {
+          if (McfStreamPtrList[i] != NULL) {
+               switch (McfStreamPtrList[i]->dos) {
+                   case MCFIO_DIRECT: case MCFIO_MEMMAPPED:
+                      mcfioC_CloseDirect(i);
+                      break;
+                   case MCFIO_SEQUENTIAL: 
+                      mcfioC_CloseSequentialTape(i);
+                      break;
+		   default:
+		      fprintf
+		       (stderr," mcf_close, Internal Error, please report \n");
+		      break;
+		      }
+             mcfioC_FreeStream(&McfStreamPtrList[i]);
+         }
+      }
+      return;
+   }
+   i = istream -1;
+   if (McfStreamPtrList[i] != NULL) {
+                switch (McfStreamPtrList[i]->dos) {
+                   case MCFIO_DIRECT: case MCFIO_MEMMAPPED:
+                      mcfioC_CloseDirect(i);
+                      break;
+                   case MCFIO_SEQUENTIAL: 
+                      mcfioC_CloseSequentialTape(i);
+                      break;
+		   default:
+		      fprintf
+		       (stderr," mcf_close, Internal Error, please report \n");
+		      break;
+		      }
+          mcfioC_FreeStream(&McfStreamPtrList[i]); 
+       }
+}
+
+void mcfioC_Rewind(int istream) 
+/* 
+** Closing a Stream istream is the F77 index to the array of mcf Streams.
+*/
+{
+   int i;
+   
+   if (McfStreamPtrList == NULL) return;
+   if ((istream <= 0) || (istream >  MCF_STREAM_NUM_MAX)) {
+      fprintf (stderr, "mcfio_Rewind, Illegal argument, stream = %d \n",
+                         istream);
+      return;
+   }   
+   i = istream -1;
+   
+   if (McfStreamPtrList[i] != NULL) {
+                if(McfStreamPtrList[i]->row == MCFIO_WRITE) {
+		     fprintf
+	   (stderr," mcf_Rewind, Not support for Output Stream \n");
+		      return;
+		   }
+                switch (McfStreamPtrList[i]->dos) {
+                   case MCFIO_DIRECT: case MCFIO_MEMMAPPED:
+                      mcfioC_RewindDirect(i);
+                      break;
+                   case MCFIO_SEQUENTIAL: 
+		      fprintf
+    (stderr," mcf_Rewind, Sequential, done by a close Sequential File\n\
+    Then reopening a stream on the same sequential  media  \n");
+                      break;
+		   default:
+		      fprintf
+		       (stderr," mcf_Rewind, Internal Error, please report \n");
+		      break;
+		      }
+		McfStreamPtrList[i]->numWordsC = 0;
+		McfStreamPtrList[i]->numWordsT = 0;
+       }
+}
+
+void mcfioC_Free_FileHeader(mcfxdrFileHeader **p)
+{
+   int i;
+   mcfxdrFileHeader *head = *p;
+   
+   if (head == NULL) return;
+   for (i=0; i<head->nBlocks; i++) 
+     if (head->blockNames[i] != NULL) free(head->blockNames[i]);
+   if (head->blockNames != NULL) free (head->blockNames); 
+   if (head->blockIds != NULL) free(head->blockIds);
+   free(head);
+   *p = NULL;
+} 
+
+void mcfioC_Free_SeqHeader(mcfxdrSequentialHeader **p)
+{
+   mcfxdrSequentialHeader *head = *p;
+   
+   if (head == NULL) return;
+   free(head);
+   *p = NULL;
+} 
+
+void mcfioC_Free_EventHeader(mcfxdrEventHeader **p)
+{
+   mcfxdrEventHeader *head = *p;
+   
+   if (head == NULL) return;
+   if (head->ptrBlocks != NULL) free(head->ptrBlocks);
+   if (head->blockIds != NULL) free(head->blockIds);
+   if (head->ptrNTuples != NULL) free(head->ptrNTuples);
+   if (head->nTupleIds != NULL) free(head->nTupleIds);
+   free(head);
+   *p = NULL;
+}
+
+void mcfioC_Free_EventTable(mcfxdrEventTable **p)
+{
+   mcfxdrEventTable *table = *p;
+   
+   if (table == NULL) return;
+   if (table->evtnums != NULL) free(table->evtnums);
+   if (table->storenums != NULL) free(table->storenums);
+   if (table->runnums != NULL) free(table->runnums);
+   if (table->trigMasks != NULL) free(table->trigMasks);
+   if (table->ptrEvents != NULL) free(table->ptrEvents);
+   free(table);
+   *p = NULL;
+}
+ 
+void mcfioC_FreeStream(mcfStream **stream)
+{
+   mcfStream *str = *stream;
+   if (str == NULL) return;
+   if (str->filename != NULL) free (str->filename);
+   if (str->device != NULL) free (str->device);
+   if (str->vsn != NULL) free (str->vsn);
+   if (str->fhead != NULL) mcfioC_Free_FileHeader(&(str->fhead)); 
+   if (str->shead != NULL) mcfioC_Free_SeqHeader(&(str->shead));
+   if (str->ehead != NULL) mcfioC_Free_EventHeader(&(str->ehead));
+   if (str->table != NULL) mcfioC_Free_EventTable(&(str->table));
+   if (str->buffer != NULL) free (str->buffer);
+   if (str->buffer2 != NULL) free (str->buffer2);
+   free(str);
+   *stream = NULL;
+   McfNumOfStreamActive--;
+}
+
+
+void mcfioC_PrintDictionary(void)
+{
+   printf (" \n");
+   printf
+    (" Mcfast I/o Dictionary for Key words used in mcfio_Info routines \n");
+   
+   printf
+    (" --------------------------------------------------------------- \n");
+   printf (" \n");
+   printf (" For Streams \n");
+   printf (" -------------- \n");
+   printf (" MCFIO_STATUS: The current status of the file;  \n");
+   printf ("               the answer can be set to: \n");
+   printf
+ ("   MCFIO_BOF : at beginning of file \n");
+   printf
+ ("   MCFIO_EOF : at the end of file \n");
+   printf 
+ ("   MCFIO_RUNNING: At least a valid file header has been read or written\n");
+   
+   printf
+    (" MCFIO_READORWRITE: if set MCFIO_READ, open for  read only \n");
+   printf
+    ("                    if set MCFIO_WRITE, open for  write only \n");
+   printf
+   (" MCFIO_DIRECTORSEQUENTIAL: if set MCFIO_DIRECT, accessing a UNIX file \n");
+   printf
+   ("                         : if set MCFIO_SEQUENTIAL, accessing a tape \n");
+   printf
+ (" MCFIO_NUMEVTS : Total number of events encode/decoded so far. \n");
+   printf
+    (" MCFIO_NUMBLOCK: The number of blocks defined in the file. \n");
+    
+   printf
+   (" MCFIO_BLOCKIDS: The I.D. of the block defined in the file.\n");
+   printf
+ (" MCFIO_NUMWORDS: Total number of 4-bytes words encode/decoded so far. \n");
+   printf
+ (" MCFIO_EFFICIENCY: The overhead in blocking and XDR (*10000 ) \n");
+   printf
+ (" MCFIO_CREATIONDATE: The date (30 Character) when the file was opened \n");
+   printf
+ (" MCFIO_CLOSINGDATE: The date (30 Character) when the file was closed \n");
+   printf
+ (" MCFIO_TITLE: The title (255 Characters max) for the job \n");
+   printf
+ (" MCFIO_COMMENT: The comment (255 Characters max) for the job \n");
+ 
+   printf (" \n");
+   printf (" For Sequential Access only \n");
+   printf 
+   ("    MCFIO_FILENUMBER : The Sequential file number currently accessed.\n");
+   printf ("    MCFIO_MAXLREC: Maximum Record length\n");
+   printf ("    MCFIO_MINLREC: Minumum Record length\n");
+   printf
+   ("    MCFIO_NUMRECORDS: The number of records in the current event\n");
+   printf 
+   ("    MCFIO_RECORDLENGTHS: The record lengths for the current event\n"); 
+   printf ("    MCFIO_DEVICENAME: The device name opened by the stream\n ");
+   printf ("                    (character string, 255 l.)\n");
+   printf (" \n");
+   printf (" For Direct Access only \n");
+   printf ("    MCFIO_FILENAME: The UNIX file name opened by the stream\n ");
+   printf ("                    (character string, 255 l.)\n");
+   
+   printf (" \n");
+   printf (" For Events \n");
+   printf (" -------------- \n");
+   printf
+    (" MCFIO_NUMBLOCK: The number of blocks defined in the event.\n");
+    
+   printf
+   (" MCFIO_BLOCKIDS: The I.D. of the block defined in the event.\n");
+   printf
+   (" MCFIO_EVENTNUMBER: The Event Number for this event. \n");
+   printf
+   (" MCFIO_STORENUMBER: The Store Number for this event. \n");
+   printf
+   (" MCFIO_RUNNUMBER: The Run Number for this event. \n");
+   printf
+   (" MCFIO_TRIGGERMASK: The Trigger Mask for this event. \n");
+   printf (" MCFIO_VERSION: The 4-Character version of the event header \n ");
+   
+   printf (" \n");
+   printf (" For Blocks \n");
+   printf (" -------------- \n");
+   printf (" MCFIO_VERSION: The 4-Character version of a particular block \n ");
+   
+   printf (" \n");
+   printf (" For NTuples \n");
+   printf (" -------------- \n");
+   printf (" MCFIO_NUMNTUPLES: The number of defined NTuples on a stream \n ");
+   printf (" See also mcfio_GetNTupleIds, mcfio_GetNTupleUID, \n");
+   printf ("           mcfio_GetNTupleCategory, mcfio_GetNTupleTitle and \n");
+   printf ("           mcfio_GetNTupleName \n");
+   
+}
+   
+unsigned int mcfioC_InfoNumStream(int *istreams,  unsigned int nmax)
+/*
+** Returns in the arrary istream the list of active stream indices.
+** 
+*/
+{
+   int i,j;
+   
+   if (nmax >= MCF_STREAM_NUM_MAX) {
+     fprintf(stderr, "mcfio_Info, Illegal size of Stream Pointer array \n");
+     return 0;
+   }   
+   for (i=0,j=0; i<MCF_STREAM_NUM_MAX; i++) {
+   	if (McfStreamPtrList[i] != NULL) { 
+          if (j < nmax) istreams[j] = McfStreamPtrList[i]->id;
+   	  j++;  
+          }
+   } 
+   return  McfNumOfStreamActive;
+}
+
+void mcfioC_InfoStreamInt(int stream, int key, int *values)
+/*
+** Information routine for the Stream.  Based on key, return in *values 
+** the requested information 
+*/
+{
+    int i, num, jstr;
+    float a;
+    mcfStream *str;
+    jstr = stream - 1;
+    if ((jstr <0) || (jstr >= MCF_STREAM_NUM_MAX)) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is illegal \n",
+                     stream);
+      return;
+    }
+    str = McfStreamPtrList[jstr];
+    if (str == NULL) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is inactive \n",
+                     stream);
+      return;
+    }
+    switch (key) {
+      case MCFIO_STATUS: 
+           *values = str->status;
+           break;
+      case MCFIO_READORWRITE:
+            *values = str->row;
+            break;
+      case MCFIO_DIRECTORSEQUENTIAL:
+            *values = str->dos;
+            break;
+      case MCFIO_NUMWORDS:
+            *values = str->numWordsT;
+            break;
+      case MCFIO_EFFICIENCY:
+            a = ((float ) (str->numWordsC))/ (float) (str->numWordsT); 
+            *values = (int) (10000. * a);
+            break;
+      case MCFIO_NUMEVTS:
+           if(str->fhead != NULL)  *values = str->fhead->numevts;
+           break;
+      case MCFIO_NUMBLOCKS:
+            if(str->fhead != NULL) *values = str->fhead->nBlocks;
+            break;
+      case MCFIO_BLOCKIDS:
+      	/* 
+      	** Crash bug possibility here, if the dimension is wrong ! 
+      	*/
+      	  if(str->fhead != NULL) {
+            for (i=0; i<str->fhead->nBlocks; i++)
+              values[i] = str->fhead->blockIds[i];
+            }
+            break;
+        /*
+        ** Now the specific items for Sequential stuff
+        */
+      case MCFIO_FILENUMBER:
+          if (str->dos != MCFIO_SEQUENTIAL) {
+             fprintf(stderr,
+ "mcfio_InfoStream: Meaningless request for stream %d, key MCFIO_FILENUMBER\n", 
+   stream);
+   	     return;
+   	    }
+            *values = str->filenumber;
+            break;
+       case MCFIO_MAXREC:
+          if (str->dos != MCFIO_SEQUENTIAL) {
+             fprintf(stderr,
+   "mcfio_InfoStream: Meaningless request for stream %d, key MCFIO_MAXREC\n", 
+   stream);
+   	     return;
+   	   }
+           *values = str->maxlrec;
+   	   break;
+       case MCFIO_MINREC:
+          if (str->dos != MCFIO_SEQUENTIAL) {
+             fprintf(stderr,
+   "mcfio_InfoStream: Meaningless request for stream %d, key MCFIO_MINREC \n", 
+   stream);
+   	     return;
+   	   }
+           *values = str->minlrec;
+   	   break;   	              
+       case MCFIO_NUMRECORDS:
+          if ((str->dos != MCFIO_SEQUENTIAL) || (str->shead == NULL) ) {
+             fprintf(stderr,
+ "mcfio_InfoStream: Meaningless request for stream %d, key MCFIO_NUMRECORDS \n", 
+   stream);
+   	     return;
+   	   }
+           *values = str->shead->nRecords;
+   	   break;
+       case MCFIO_RECORDLENGTHS:
+          if ((str->dos != MCFIO_SEQUENTIAL) || (str->shead == NULL) ) {
+             fprintf(stderr,
+ "mcfio_InfoStream: Meaningless request for stream %d, key MCFIO_RECORDLENGTHS \n", 
+   stream);
+   	     return;
+   	   }
+   	   *values = str->maxlrec;
+   	   break;
+       case MCFIO_NUMNTUPLES:
+          for (i=0, num=0; i<NumOfNTuples; i++)
+               if (NTuDDLList[i]->streamId == stream) num++; 
+          *values = num;
+          break;            
+      default:
+            fprintf(stderr,
+             "mcfio_InfoStream: Unrecognized Keyword %d\n", key);
+    }
+}
+
+void mcfioC_InfoStreamChar(int stream, int key, char *answer, int *lret)
+/*
+** Information routine for the Stream.  Based on key, return in *values 
+** the requested information 
+*/
+{
+    int jstr;
+    mcfStream *str;
+    jstr = stream - 1;
+    if ((jstr <0) || (jstr >= MCF_STREAM_NUM_MAX)) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is illegal \n",
+                     stream);
+      *lret = 0;
+      return;
+    }
+    str = McfStreamPtrList[jstr];
+    if (str == NULL) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is inactive \n",
+                     stream);
+      *lret = 0;
+      return;
+    }
+    switch (key) {
+      case MCFIO_TITLE:
+            if (str->fhead != NULL) strcpy(answer,str->fhead->title);
+            break;
+      case MCFIO_COMMENT:
+            if (str->fhead != NULL) strcpy(answer,str->fhead->comment);
+            break;
+      case MCFIO_CREATIONDATE:
+            if (str->fhead != NULL) strcpy(answer,str->fhead->date);
+            break;
+      case MCFIO_CLOSINGDATE:
+            if (str->fhead != NULL) strcpy(answer,str->fhead->closingDate);
+            break;
+      case MCFIO_FILENAME:
+          if (str->dos == MCFIO_SEQUENTIAL) {
+             fprintf(stderr,
+   "mcfio_InfoStream: Meaningless request for stream %d, key MCFIO_FILENAME \n", 
+   stream);
+             *lret = 0;
+   	     return;
+   	   }
+            strcpy(answer,str->filename);
+            break;
+      case MCFIO_DEVICENAME:
+          if (str->dos != MCFIO_SEQUENTIAL) {
+             fprintf(stderr,
+ "mcfio_InfoStream: Meaningless request for stream %d, key MCFIO_DEVICENAME \n", 
+   stream);
+             *lret = 0;
+   	     return;
+   	   }
+            strcpy(answer,str->device);
+            break;
+      default:
+            fprintf(stderr,
+             "mcfio_InfoStream: Unrecognized Keyword %d\n", key);
+             *lret = 0;
+   	     return;
+                           
+    }
+    *lret = strlen(answer);
+} 
+void mcfioC_InfoEventInt(int stream, int key, int *values)
+/*
+** Information routine for the current Event.  
+**   Based on key, return in *values the requested information 
+*/
+{
+    int i, jstr;
+    mcfStream *str;
+    jstr = stream - 1;
+    if ((jstr <0) || (jstr >= MCF_STREAM_NUM_MAX)) {
+      fprintf(stderr,"mcfio_InfoEvent: Stream id %d is illegal \n",
+                     stream);
+      return;
+    }
+    str = McfStreamPtrList[jstr];
+    if (str == NULL) {
+      fprintf(stderr,"mcfio_InfoEvent: Stream id %d is inactive \n",
+                     stream);
+      return;
+    }
+    if (str->ehead ==NULL) {
+      fprintf(stderr,"mcfio_InfoEvent: Stream id %d is at beginning \n",
+                     stream);
+      return;
+    }  
+    switch (key) {
+      case MCFIO_EVENTNUMBER:
+       *values = str->ehead->evtnum;
+       break;
+      case MCFIO_STORENUMBER:
+       *values = str->ehead->storenum;
+       break;
+      case MCFIO_RUNNUMBER:
+       *values = str->ehead->runnum;
+       break;
+      case MCFIO_TRIGGERMASK:
+       *values = str->ehead->trigMask;
+       break;
+      case MCFIO_NUMBLOCKS:
+       *values = str->ehead->nBlocks;
+       break;
+      case MCFIO_BLOCKIDS:
+       for(i=0; i<str->ehead->nBlocks; i++) 
+               values[i] = str->ehead->blockIds[i];
+       break;        
+      case MCFIO_NUMNTUPLES:
+        *values = str->ehead->nNTuples;
+        break;
+      case MCFIO_NTUPLESLIST:
+       for(i=0; i<str->ehead->nNTuples; i++) 
+               values[i] = str->ehead->nTupleIds[i];
+       break;
+      default:
+            fprintf(stderr,
+             "mcfio_InfoEvent: Unrecognized Keyword %d\n", key);
+                      
+    }
+}
+ 
+void mcfioC_SetEventInfo(int stream, int key, int *values)
+/*
+** Set anciallary information for the current Event.  
+**   Based on key, return in *values the requested information 
+**   Only valid for Output Streams. 
+*/
+{
+    int jstr;
+    mcfStream *str;
+    jstr = stream - 1;
+    if ((jstr <0) || (jstr >= MCF_STREAM_NUM_MAX)) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is illegal \n",
+                     stream);
+      return;
+    }
+    str = McfStreamPtrList[jstr];
+    if (str == NULL) {
+      fprintf(stderr,"mcfio_SetEvent: Stream id %d is inactive \n",
+                     stream);
+      return;
+    }
+    if (str->ehead ==NULL) {
+      fprintf(stderr,"mcfio_SetEvent: Stream id %d is at beginning \n",
+                     stream);
+      return;
+    }
+    if (str->row != MCFIO_WRITE) {  
+      fprintf(stderr,
+      "mcfio_SetEvent: Stream id %d must be an Output stream \n",
+                     stream);
+      return;
+    }
+    switch (key) {
+      case MCFIO_EVENTNUMBER:
+       str->ehead->evtnum = *values;
+       break;
+      case MCFIO_STORENUMBER:
+       str->ehead->storenum = *values;
+       break;
+      case MCFIO_RUNNUMBER:
+       str->ehead->runnum = *values;
+       break;
+      case MCFIO_TRIGGERMASK:
+       str->ehead->trigMask = *values;
+       break;
+      case MCFIO_NUMBLOCKS: case MCFIO_BLOCKIDS:
+      fprintf(stderr,
+  "mcfio_SetEvent: Blocks and Block contents are set by mcfio_Blocks\n" );
+      return;
+      default:
+            fprintf(stderr,
+             "mcfio_SetEvent: Unrecognized Keyword %d\n", key);
+                      
+    }
+} 
+
+void mcfioC_InfoEventChar(int stream, int key, char *answer, int *lret)
+/*
+** Information routine for the current Event.  
+**   Based on key, return in *values the requested information 
+*/
+{
+    int jstr;
+    mcfStream *str;
+    jstr = stream - 1;
+    if ((jstr <0) || (jstr >= MCF_STREAM_NUM_MAX)) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is illegal \n",
+                     stream);
+      *lret = 0;
+      return;
+    }
+    str = McfStreamPtrList[jstr];
+    if (str == NULL) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is inactive \n",
+                     stream);
+      *lret = 0;
+      return;
+    }
+    if (str->ehead ==NULL) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is at beginning \n",
+                     stream);
+      *lret = 0;
+      return;
+    }  
+    switch (key) {
+      case MCFIO_VERSION:
+       strcpy(answer, str->ehead->version);
+       break;
+      
+      default:
+            fprintf(stderr,
+             "mcfio_InfoEvent: Unrecognized Keyword %d\n", key);
+            *lret = 0;
+            return;
+                      
+    }
+    *lret = strlen(answer);
+} 
+
+void mcfioC_InfoBlockChar(int stream, int blkid,
+                            int key, char *answer, int *lret)
+/*
+** Information routine for a particular block within the current Event.  
+**   Based on key, return the requested information in string answer.
+*/
+{
+    int i, jstr, itmp, nn;
+    u_int pos;
+    bool_t tt;
+    char* data, *vv;
+    mcfStream *str;
+    jstr = stream - 1;
+    if ((jstr <0) || (jstr >= MCF_STREAM_NUM_MAX)) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is illegal \n",
+                     stream);
+      *lret = 0;               
+      return;
+    }
+    str = McfStreamPtrList[jstr];
+    if (str == NULL) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is inactive \n",
+                     stream);
+      *lret = 0;               
+      return;
+    }
+    if (str->ehead ==NULL) {
+      fprintf(stderr,"mcfio_InfoStream: Stream id %d is at beginning \n",
+                     stream);
+      *lret = 0;               
+      return;
+    }
+    pos = 0;
+    if(str->xdr != NULL) for(i=0; i<str->ehead->nBlocks; i++) 
+      if( str->ehead->blockIds[i] == blkid) pos = str->ehead->ptrBlocks[i];
+    if (pos == 0) {
+      fprintf(stderr,
+      "mcfio_InfoStream: Stream id %d event %d does not contain block %d \n",
+             stream,str->ehead->evtnum, blkid );
+      *lret = 0;               
+      return;
+    }
+     
+    switch (key) {
+      case MCFIO_VERSION:
+       tt = xdr_setpos(str->xdr, pos); 
+       tt = xdr_mcfast_generic(str->xdr, &itmp, &nn, &vv, &data);
+       xdr_free((void *) xdr_string, data); 
+       strcpy(answer, vv);
+       break;
+      
+      default:
+            fprintf(stderr,
+             "mcfio_InfoEvent: Unrecognized Keyword %d\n", key);
+            *lret = 0;
+            return;               
+                      
+    }
+    *lret = strlen(answer);
+} 
+void mcfioC_GetBlockName(int blkId, char *answer)
+/*
+**  Get a Block name from the dictionary..It is assume that answer has 
+**     pre-malloc, size MCF_XDR_B_TITLE_LENGTH 
+*/
+{
+   char *uDescr;
+    switch (blkId) {
+       case MCFIO_STDHEP:
+         strcpy(answer,
+         " Standard HEP COMMON block, see STDHEP Product");
+         break;
+         
+       case MCFIO_STDHEPM:
+         strcpy(answer,
+         " Standard HEP COMMON block with multiple interaction, see STDHEP Product");
+         break;
+         
+       case MCFIO_STDHEP4:
+         strcpy(answer,
+         " Standard HEP COMMON block with Les Houches, see STDHEP Product");
+         break;
+         
+       case MCFIO_STDHEP4M:
+         strcpy(answer,
+         " Standard HEP COMMON block with Les Houches and multiple interaction");
+         break;
+         
+       case MCFIO_HEPEUP:
+         strcpy(answer,
+         " Les Houches HEPEUP common block");
+         break;
+         
+       case MCFIO_HEPRUP:
+         strcpy(answer,
+         " Les Houches HEPRUP common block");
+         break;
+         
+       case MCFIO_STDHEPCXX:
+         strcpy(answer,
+         " StdHep::Event class, see StdHepC++ Product");
+         break;
+         
+       case MCFIO_STDHEPBEG:
+         strcpy(answer,
+         " Stdhep begin run record, see STDHEP Product");
+         break;
+         
+       case MCFIO_STDHEPEND:
+         strcpy(answer,
+         " Stdhep end run record, see STDHEP Product");
+         break;
+         
+       case MCFIO_OFFTRACKARRAYS:
+         strcpy(answer,
+         " The mcfast Offline Tracks, saved into parallel arrays");
+         break;
+         
+       case MCFIO_OFFTRACKSTRUCT:
+         strcpy(answer,
+         " The mcfast Offline Tracks, saved as the structure");
+         break;
+       default:          
+         sprintf(answer, " Private User Block number %d ", blkId );
+	 uDescr = mcfioC_UserBlockDescript(blkId);
+	 if (uDescr == NULL) fprintf(stderr,
+          "mcfio_GetBlockName: Warning Unrecognized block I.D. %d\n", blkId);
+         else answer = uDescr;             
+  }         
+	
+}
+
+
+
Index: /trunk/Utilities/mcfio/mcfio_Util1.h
===================================================================
--- /trunk/Utilities/mcfio/mcfio_Util1.h	(revision 3)
+++ /trunk/Utilities/mcfio/mcfio_Util1.h	(revision 3)
@@ -0,0 +1,25 @@
+/*******************************************************************************
+*									       *
+* mcfio_Util1.h --  Include file for mcfast initialisation & info i/o layer.   *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+*									       *
+*******************************************************************************/
+void mcfioC_Init(void);
+void mcfioC_Close(int istream);
+void mcfioC_PrintDictionary(void);
+unsigned int mcfioC_InfoNumSream(int *istreams, unsigned int nmax);
+void mcfioC_InfoStreamInt(int istream, int key, int *value);
+void mcfioC_InfoStreamChar(int istream, int key, char *answer, int *lret);
+void mcfioC_InfoEventInt(int istream, int key, int *value);
+void mcfioC_InfoEventChar(int istream, int key, char *answer, int *lret);
+void mcfioC_SetEventInfo(int istream, int key, int *value);
+void mcfioC_Free_FileHeader(mcfxdrFileHeader **p);
+void mcfioC_Free_SeqHeader(mcfxdrSequentialHeader **p);
+void mcfioC_Free_EventHeader(mcfxdrEventHeader **p);
+void mcfioC_Free_EventTable(mcfxdrEventTable **p);
+void mcfioC_FreeStream(mcfStream **stream);
+void mcfioC_InfoBlockChar(int stream, int blk, int key,
+                            char *answer, int *lret);
+void mcfioC_GetBlockName(int blkId, char *answer);
Index: /trunk/Utilities/stdhep/CREDITS
===================================================================
--- /trunk/Utilities/stdhep/CREDITS	(revision 3)
+++ /trunk/Utilities/stdhep/CREDITS	(revision 3)
@@ -0,0 +1,1 @@
+not available
Index: /trunk/Utilities/stdhep/VERSION
===================================================================
--- /trunk/Utilities/stdhep/VERSION	(revision 3)
+++ /trunk/Utilities/stdhep/VERSION	(revision 3)
@@ -0,0 +1,1 @@
+not available
Index: /trunk/Utilities/stdhep/hepeup.h
===================================================================
--- /trunk/Utilities/stdhep/hepeup.h	(revision 3)
+++ /trunk/Utilities/stdhep/hepeup.h	(revision 3)
@@ -0,0 +1,21 @@
+/*
+C...User process event common block.
+*/
+
+#define MAXNUP 500
+struct hepeup {
+  int nup;		/* number of particles */
+  int idprup;
+  double xwgtup;
+  double scalup;
+  double aqedup;
+  double aqcdup;
+  int idup[MAXNUP];
+  int istup[MAXNUP];
+  int mothup[MAXNUP][2];
+  int icolup[MAXNUP][2];
+  double pup[MAXNUP][5];
+  double vtimup[MAXNUP];
+  double spinup[MAXNUP];
+};
+
Index: /trunk/Utilities/stdhep/hepev4.h
===================================================================
--- /trunk/Utilities/stdhep/hepev4.h	(revision 3)
+++ /trunk/Utilities/stdhep/hepev4.h	(revision 3)
@@ -0,0 +1,22 @@
+/* Hepev4 holds Les Houches information */
+/*  note that to avoid alignment problems, structures and common blocks
+    should be in the order: double precision, real, integer.
+*/
+struct hepev4 {
+  double eventweightlh;			/* event weight */
+  double alphaqedlh; 			/* QED coupling alpha_em */
+  double alphaqcdlh;			/* QCD coupling alpha_s */
+  double scalelh[10]; 			/* Scale Q of the event */
+  double spinlh[NMXHEP][3]; 		/* spin information */
+  int    icolorflowlh[NMXHEP][2]; 	/* (Anti-)Colour flow */
+  int    idruplh;			/* ID, as given by LPRUP codes */
+};
+
+struct hepev5 {
+  double eventweightmulti[NMXMLT];	/* original event weight */
+  double alphaqedmulti[NMXMLT]; 	/* original QED coupling alpha_em */
+  double alphaqcdmulti[NMXMLT];		/* original QCD coupling alpha_s */
+  double scalemulti[NMXMLT][10]; 	/* original Scale Q of the event */
+  int    idrupmulti[NMXMLT];		/* original ID, as given by LPRUP codes */
+};
+
Index: /trunk/Utilities/stdhep/heprup.h
===================================================================
--- /trunk/Utilities/stdhep/heprup.h	(revision 3)
+++ /trunk/Utilities/stdhep/heprup.h	(revision 3)
@@ -0,0 +1,17 @@
+/*
+C...User process initialization commonblock.
+*/
+
+#define MAXPUP 100
+struct heprup {
+  int idbmup[2];
+  double ebmup[2];
+  int pdfgup[2];
+  int pdfsup[2];
+  int idwtup;
+  int nprup;
+  double xsecup[MAXPUP];
+  double xerrup[MAXPUP];
+  double xmaxup[MAXPUP];
+  int lprup[MAXPUP];
+};
Index: /trunk/Utilities/stdhep/mcf_Stdhep_xdr.c
===================================================================
--- /trunk/Utilities/stdhep/mcf_Stdhep_xdr.c	(revision 3)
+++ /trunk/Utilities/stdhep/mcf_Stdhep_xdr.c	(revision 3)
@@ -0,0 +1,238 @@
+/*******************************************************************************
+*									       *
+* mcf_Stdhep_xdr.c -- XDR Utility routines for the Block Stdhep filters        *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Paul Lebrun, Lynn Garren					       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <rpc/xdr.h>
+#include <limits.h>
+#ifdef SUNOS
+#include <floatingpoint.h>
+#else /* SUNOS */
+#include <float.h>
+#endif /* SUNOS */
+#include <stdlib.h>
+#include <time.h>
+#include "Utilities/mcfio/mcfio_Dict.h"
+#include "Utilities/mcfio/mcf_xdr.h"
+#include "Utilities/stdhep/stdhep.h"
+#include "Utilities/stdhep/stdtmp.h"
+#include "Utilities/stdhep/stdver.h"
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+extern struct stdver stdver_;
+extern struct hepevt myhepevt;
+extern struct hepev2 hepev2_;
+extern struct hepev3 hepev3_;
+extern struct stdtmp stdtmp_;
+
+bool_t xdr_stdhep_(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version)
+
+{
+/*  Translate the HEPEVT temporary COMMON block from the STDHEP package to/from
+    an XDR stream. Note that we do not allocate memory, because we fill
+    directly the COMMON.  Also, mcfio will allocate the space for the 
+    string version.  */
+    
+    unsigned int nn, nn2, nn4, nn5, nnw, nnw2, nnw4, nnw5;
+    int *idat;
+    double *dat;
+    
+    if ((xdrs->x_op == XDR_ENCODE) || (xdrs->x_op == XDR_MCFIOCODE))  {
+       if (*blockid != MCFIO_STDHEP) {
+          fprintf (stderr, "mcf_Stdhep_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+       }
+
+       nn =  (unsigned int) stdtmp_.nhept;   /* Number of elements in isthep or idhep     */
+       nn2 = 2*(unsigned int) stdtmp_.nhept; /* Number of elements in jmohep or jdahep    */
+       nn4 = 4*(unsigned int) stdtmp_.nhept; /* Number of elements in vhep                */
+       nn5 = 5*(unsigned int) stdtmp_.nhept; /* Number of elements in phep                */
+       nnw = (unsigned int) stdtmp_.nhept;
+       nnw2 = 2 * nnw;
+       nnw4 = 4 * nnw;
+       nnw5 = 5 * nnw;
+
+       /* Total length in bytes include blockid, ntot, version, nevhept and nhept as well
+          as the arrays remembering doubles are longer than ints.                         */
+       *ntot = 5*sizeof(int) + sizeof(int)*(2*nn + 2*nn2) + sizeof(double)*(nn4 + nn5);
+
+       if (xdrs->x_op == XDR_MCFIOCODE) return TRUE;
+       strncpy(version[0],stdver_.stdhep_ver, 4);
+       } 
+      
+     if     ( (xdr_int(xdrs, blockid) &&
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH) &&
+     	      xdr_int(xdrs, &(stdtmp_.nevhept)) &&
+              xdr_int(xdrs, &(stdtmp_.nhept))) == FALSE) return FALSE;
+              
+     if ((xdrs->x_op == XDR_DECODE) && ( *blockid != MCFIO_STDHEP) ) {
+          fprintf (stderr, "mcf_Stdhep_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+     }
+     idat = stdtmp_.isthept;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+         &nnw, NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = stdtmp_.idhept;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+         &nnw, NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = (int *) stdtmp_.jmohept;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+                &nnw2, 2*NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = (int *) stdtmp_.jdahept;
+     if     ( xdr_array(xdrs,  (char **)   &idat,
+                &nnw2, 2*NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     dat = (double *)  stdtmp_.phept;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+                &nnw5, 5*NMXHEP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     dat = (double *) stdtmp_.vhept;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &nnw4, 4*NMXHEP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     return TRUE;
+}   
+
+bool_t xdr_stdhep_multi_(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version)
+
+{
+/*  Translate the HEPEVT COMMON block from the STDHEP package to/from
+    an XDR stream. Note that we do not allocate memory, because we fill
+    directly the COMMON.  Also, mcfio will allocate the space for the 
+    string version. 
+    Also translate the HEPEV2 COMMON block from the STDHEP package to/from
+    an XDR stream. HEPEV2 contains multiple interaction information */
+    
+    unsigned int nn, nn2, nn4, nn5, nnw, nnw2, nnw4, nnw5, nmlt, nnmlt;
+    int i;
+    int *idat;
+    char *vers;
+    double *dat;
+    
+    if ((xdrs->x_op == XDR_ENCODE) || (xdrs->x_op == XDR_MCFIOCODE))  {
+       if (*blockid != MCFIO_STDHEPM) {
+          fprintf (stderr, "mcf_Stdhep_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+       }
+       nn = sizeof(int) * myhepevt.nhep;
+       nn2 = 2 * sizeof(int) * myhepevt.nhep;
+       nn4 = 4 * sizeof(double) * myhepevt.nhep;
+       nn5 = 5 * sizeof(double) * myhepevt.nhep;
+       nmlt = sizeof(int) * hepev2_.nmulti;
+       nnw = (unsigned int) myhepevt.nhep;
+       nnw2 = 2 * nnw;
+       nnw4 = 4 * nnw;
+       nnw5 = 5 * nnw;
+       nnmlt = (unsigned int) hepev2_.nmulti;
+       *ntot = 6 * sizeof(int) + 3 * nn + 2 * nn2 + nn4 + nn5 + 3 * nmlt;
+       if (xdrs->x_op == XDR_MCFIOCODE) return TRUE;
+       strncpy(version[0],stdver_.stdhep_ver, 4);
+       } 
+      
+     if     ( (xdr_int(xdrs, blockid) &&
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH) &&
+     	      xdr_int(xdrs, &(myhepevt.nevhep)) &&
+              xdr_int(xdrs, &(myhepevt.nhep))) == FALSE) return FALSE;
+              
+     if ((xdrs->x_op == XDR_DECODE) && ( *blockid != MCFIO_STDHEPM) ) {
+          fprintf (stderr, "mcf_Stdhep_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+     }
+     idat = myhepevt.isthep;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+            &nnw, NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = myhepevt.idhep;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+            &nnw, NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = (int *) myhepevt.jmohep;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+                &nnw2, 2*NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = (int *) myhepevt.jdahep;
+     if     ( xdr_array(xdrs,  (char **)   &idat,
+                &nnw2, 2*NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     dat = (double *)  myhepevt.phep;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+                &nnw5, 5*NMXHEP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     dat = (double *) myhepevt.vhep;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &nnw4, 4*NMXHEP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     /*
+     ** V2.02 Upgrade : adding Multiple interactions. 
+     */ 
+     vers = *version;          
+     if ((strcmp(vers,"1.05") == 0)  && (xdrs->x_op == XDR_DECODE)) {
+           hepev2_.nmulti = -1;
+           return TRUE;
+     }      
+     if ( xdr_int(xdrs, &(hepev2_.nmulti)) == FALSE) return FALSE;
+     idat = hepev2_.jmulti;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+         &nnw, NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     /*
+     ** V4.04 Upgrade : adding more Multiple interaction information
+     */ 
+     if (((strcmp(vers,"2.") > 0) || (strcmp(vers,"3.") > 0)) 
+            && (xdrs->x_op == XDR_DECODE)) {
+	   for (i = 0; i <= NMXMLT; i++) {
+	       hepev3_.nevmulti[i] = 0;
+	       hepev3_.itrkmulti[i] = 0;
+	       hepev3_.mltstr[i] = 0;
+	   }
+           return TRUE;
+     }      
+     if (((strcmp(vers,"4.00") == 0) || (strcmp(vers,"4.01") == 0) ||
+          (strcmp(vers,"4.02") == 0) || (strcmp(vers,"4.03") == 0) )  
+            && (xdrs->x_op == XDR_DECODE)) {
+	   for (i = 0; i <= NMXMLT; i++) {
+	       hepev3_.nevmulti[i] = 0;
+	       hepev3_.itrkmulti[i] = 0;
+	       hepev3_.mltstr[i] = 0;
+	   }
+           return TRUE;
+     }      
+     idat = hepev3_.nevmulti;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+            &nnmlt, NMXMLT, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = hepev3_.itrkmulti;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+            &nnmlt, NMXMLT, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = hepev3_.mltstr;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+            &nnmlt, NMXMLT, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     return TRUE;
+}   
+
+
Index: /trunk/Utilities/stdhep/mcf_hepev4_xdr.c
===================================================================
--- /trunk/Utilities/stdhep/mcf_hepev4_xdr.c	(revision 3)
+++ /trunk/Utilities/stdhep/mcf_hepev4_xdr.c	(revision 3)
@@ -0,0 +1,273 @@
+/*******************************************************************************
+*									       *
+* mcf_hepev4_xdr.c -- XDR Utility routines for the Block Stdhep filters        *
+*		      hepevt and hepev4 (and optionally hepev2 and hepev3)     *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Paul Lebrun, Lynn Garren					       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <rpc/xdr.h>
+#include <limits.h>
+#ifdef SUNOS
+#include <floatingpoint.h>
+#else /* SUNOS */
+#include <float.h>
+#endif /* SUNOS */
+#include <stdlib.h>
+#include <time.h>
+#include "Utilities/mcfio/mcfio_Dict.h"
+#include "Utilities/mcfio/mcf_xdr.h"
+#include "Utilities/stdhep/stdhep.h"
+#include "Utilities/stdhep/hepev4.h"
+#include "Utilities/stdhep/stdtmp.h"
+#include "Utilities/stdhep/stdver.h"
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+extern struct stdver stdver_;
+extern struct hepevt myhepevt;
+extern struct hepev2 hepev2_;
+extern struct hepev3 hepev3_;
+extern struct hepev4 hepev4_;
+extern struct hepev5 hepev5_;
+extern struct stdtmp stdtmp_;
+extern struct tmpev4 tmpev4_;
+
+bool_t xdr_stdhep_4_(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version)
+
+{
+/*  Translate the HEPEVT temporary COMMON block from the STDHEP package to/from
+    an XDR stream. Note that we do not allocate memory, because we fill
+    directly the COMMON.  Also, mcfio will allocate the space for the 
+    string version.  */
+    
+    unsigned int nn, nn2, nn3, nn4, nn5, nnw, nnw2, nnw3, nnw4, nnw5;
+    int *idat;
+    double *dat;
+    unsigned int n5 = 5;	/* for scale */
+    
+    if ((xdrs->x_op == XDR_ENCODE) || (xdrs->x_op == XDR_MCFIOCODE))  {
+       if (*blockid != MCFIO_STDHEP4) {
+          fprintf (stderr, "mcf_hepev4_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+       }
+
+       nn =  (unsigned int) stdtmp_.nhept;   /* Number of elements in isthep or idhep     */
+       nn2 = 2*(unsigned int) stdtmp_.nhept; /* Number of elements in jmohep or jdahep    */
+       nn3 = 3*(unsigned int) stdtmp_.nhept; /* Number of elements in spinlh              */
+       nn4 = 4*(unsigned int) stdtmp_.nhept; /* Number of elements in vhep                */
+       nn5 = 5*(unsigned int) stdtmp_.nhept; /* Number of elements in phep                */
+       nnw = (unsigned int) stdtmp_.nhept;
+       nnw2 = 2 * nnw;
+       nnw3 = 3 * nnw;
+       nnw4 = 4 * nnw;
+       nnw5 = 5 * nnw;
+
+       /* Total length in bytes include blockid, ntot, version, nevhept and nhept as well
+          as the arrays remembering doubles are longer than ints.                         */
+       *ntot = 5*sizeof(int) + sizeof(int)*(2*nn + 2*nn2) 
+               + sizeof(double)*(nn4 + nn5) 
+	       + (8 + nn3)*sizeof(double) + (1 + nn2)*sizeof(int);
+
+       if (xdrs->x_op == XDR_MCFIOCODE) return TRUE;
+       strncpy(version[0],stdver_.stdhep_ver, 4);
+       } 
+      
+     if     ( (xdr_int(xdrs, blockid) &&
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH) &&
+     	      xdr_int(xdrs, &(stdtmp_.nevhept)) &&
+              xdr_int(xdrs, &(stdtmp_.nhept))) == FALSE) return FALSE;
+              
+     if ((xdrs->x_op == XDR_DECODE) && ( *blockid != MCFIO_STDHEP4) ) {
+          fprintf (stderr, "mcf_hepev4_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+     }
+     idat = stdtmp_.isthept;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+         &nnw, NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = stdtmp_.idhept;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+         &nnw, NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = (int *) stdtmp_.jmohept;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+                &nnw2, 2*NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = (int *) stdtmp_.jdahept;
+     if     ( xdr_array(xdrs,  (char **)   &idat,
+                &nnw2, 2*NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     dat = (double *)  stdtmp_.phept;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+                &nnw5, 5*NMXHEP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     dat = (double *) stdtmp_.vhept;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &nnw4, 4*NMXHEP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     /* valid for stdhep 5.01 and later */
+     if ( xdr_double(xdrs, &(tmpev4_.eventweightt) ) == FALSE) return FALSE;
+     if ( xdr_double(xdrs, &(tmpev4_.alphaqedt) ) == FALSE) return FALSE;
+     if ( xdr_double(xdrs, &(tmpev4_.alphaqcdt) ) == FALSE) return FALSE;
+     dat = (double *) tmpev4_.scalet;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &n5, 10, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     dat = (double *) tmpev4_.spint;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &nnw3, 3*NMXHEP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     idat = (int *) tmpev4_.icolorflowt;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+                &nnw2, 2*NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     if ( xdr_int(xdrs, &(tmpev4_.idrupt) ) == FALSE) return FALSE;
+     return TRUE;
+}   
+
+bool_t xdr_stdhep_4_multi_(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version)
+
+{
+/*  Translate the HEPEVT COMMON block from the STDHEP package to/from
+    an XDR stream. Note that we do not allocate memory, because we fill
+    directly the COMMON.  Also, mcfio will allocate the space for the 
+    string version. 
+    Also translate the HEPEV2 COMMON block from the STDHEP package to/from
+    an XDR stream. HEPEV2 contains multiple interaction information */
+    
+    unsigned int nn, nn2, nn3, nn4, nn5, nnw, nnw2, nnw3, nnw4, nnw5;
+    unsigned int nmlt, nnmlt, nmltd, nnmlt5;
+    int *idat;
+    double *dat;
+    unsigned int n5 = 10;	/* for scale */
+    
+    if ((xdrs->x_op == XDR_ENCODE) || (xdrs->x_op == XDR_MCFIOCODE))  {
+       if (*blockid != MCFIO_STDHEP4M) {
+          fprintf (stderr, "mcf_hepev4_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+       }
+       nn = sizeof(int) * myhepevt.nhep;
+       nn2 = 2 * sizeof(int) * myhepevt.nhep;
+       nn3 = 3 * sizeof(double) * myhepevt.nhep;
+       nn4 = 4 * sizeof(double) * myhepevt.nhep;
+       nn5 = 10 * sizeof(double) * myhepevt.nhep;
+       nmlt = sizeof(int) * hepev2_.nmulti;
+       nmltd = sizeof(double) * hepev2_.nmulti;
+       nnw = (unsigned int) myhepevt.nhep;
+       nnw2 = 2 * nnw;
+       nnw3 = 3 * nnw;
+       nnw4 = 4 * nnw;
+       nnw5 = 5 * nnw;
+       nnmlt = (unsigned int) hepev2_.nmulti;
+       nnmlt5 = 5 * nnmlt;
+       *ntot = 6 * sizeof(int) + 3 * nn + 2 * nn2 + nn4 + nn5 + 3 * nmlt
+              + nn3 + 8 * sizeof(double) + nn2 + sizeof(int)
+	      + 8 * nmltd + nmlt;
+       if (xdrs->x_op == XDR_MCFIOCODE) return TRUE;
+       strncpy(version[0],stdver_.stdhep_ver, 4);
+       } 
+      
+     if     ( (xdr_int(xdrs, blockid) &&
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH) &&
+     	      xdr_int(xdrs, &(myhepevt.nevhep)) &&
+              xdr_int(xdrs, &(myhepevt.nhep))) == FALSE) return FALSE;
+              
+     if ((xdrs->x_op == XDR_DECODE) && ( *blockid != MCFIO_STDHEP4M) ) {
+          fprintf (stderr, "mcf_hepev4_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+     }
+     idat = myhepevt.isthep;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+            &nnw, NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = myhepevt.idhep;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+            &nnw, NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = (int *) myhepevt.jmohep;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+                &nnw2, 2*NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = (int *) myhepevt.jdahep;
+     if     ( xdr_array(xdrs,  (char **)   &idat,
+                &nnw2, 2*NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     dat = (double *)  myhepevt.phep;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+                &nnw5, 5*NMXHEP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     dat = (double *) myhepevt.vhep;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &nnw4, 4*NMXHEP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     /*
+     ** V2.02 Upgrade : adding Multiple interactions. 
+     */ 
+     if ( xdr_int(xdrs, &(hepev2_.nmulti)) == FALSE) return FALSE;
+     idat = hepev2_.jmulti;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+         &nnw, NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     /*
+     ** V4.04 Upgrade : adding more Multiple interaction information
+     */ 
+     idat = hepev3_.nevmulti;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+            &nnmlt, NMXMLT, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = hepev3_.itrkmulti;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+            &nnmlt, NMXMLT, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = hepev3_.mltstr;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+            &nnmlt, NMXMLT, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     /* valid for stdhep 5.01 and later */
+     if ( xdr_double(xdrs, &(hepev4_.eventweightlh) ) == FALSE) return FALSE;
+     if ( xdr_double(xdrs, &(hepev4_.alphaqedlh) ) == FALSE) return FALSE;
+     if ( xdr_double(xdrs, &(hepev4_.alphaqcdlh) ) == FALSE) return FALSE;
+     dat = (double *) hepev4_.scalelh;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &n5, 10, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     dat = (double *) hepev4_.spinlh;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &nnw3, 3*NMXHEP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     idat = (int *) hepev4_.icolorflowlh;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+                &nnw2, 2*NMXHEP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     if ( xdr_int(xdrs, &(hepev4_.idruplh) ) == FALSE) return FALSE;
+     dat = (double *) hepev5_.eventweightmulti;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &nnmlt, NMXMLT, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     dat = (double *) hepev5_.alphaqedmulti;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &nnmlt, NMXMLT, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     dat = (double *) hepev5_.alphaqcdmulti;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &nnmlt, NMXMLT, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     dat = (double *) hepev5_.scalemulti;
+     if     ( xdr_array(xdrs, (char **)    &dat,
+                &nnmlt5, 10*NMXMLT, sizeof(double), (void *) xdr_double) == FALSE) return FALSE;
+     idat = hepev5_.idrupmulti;
+     if     ( xdr_array(xdrs, (char **)   &idat,
+            &nnmlt, NMXMLT, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     return TRUE;
+}   
+
+
Index: /trunk/Utilities/stdhep/mcf_hepup_xdr.c
===================================================================
--- /trunk/Utilities/stdhep/mcf_hepup_xdr.c	(revision 3)
+++ /trunk/Utilities/stdhep/mcf_hepup_xdr.c	(revision 3)
@@ -0,0 +1,196 @@
+/*******************************************************************************
+*									       *
+* mcf_hepup_xdr.c -- XDR Utility routines for the Block Stdhep filters        *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Paul Lebrun, Lynn Garren					       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <rpc/xdr.h>
+#include <limits.h>
+#ifdef SUNOS
+#include <floatingpoint.h>
+#else /* SUNOS */
+#include <float.h>
+#endif /* SUNOS */
+#include <stdlib.h>
+#include <time.h>
+#include "Utilities/mcfio/mcfio_Dict.h"
+#include "Utilities/mcfio/mcf_xdr.h"
+#include "Utilities/stdhep/hepeup.h"
+#include "Utilities/stdhep/heprup.h"
+#include "Utilities/stdhep/stdver.h"
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+extern struct stdver stdver_;
+extern struct hepeup hepeup_;
+extern struct heprup heprup_;
+
+bool_t xdr_hepeup_(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version)
+
+{
+/*  Translate the HEPEUP COMMON block from the STDHEP package to/from
+    an XDR stream. Note that we do not allocate memory, because we fill
+    directly the COMMON.  Also, mcfio will allocate the space for the 
+    string version.  */
+    
+    unsigned int nn, nn2, nn5;
+    int *idat;
+    double *dat;
+    
+    if ((xdrs->x_op == XDR_ENCODE) || (xdrs->x_op == XDR_MCFIOCODE))  {
+       if (*blockid != MCFIO_HEPEUP) {
+          fprintf (stderr, "mcf_hepup_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+       }
+
+       nn =  (unsigned int) hepeup_.nup;   /* Number of elements in idup, istup, vtimup, spinup */
+       nn2 = 2*(unsigned int) hepeup_.nup; /* Number of elements in mothup, icolup    */
+       nn5 = 5*(unsigned int) hepeup_.nup; /* Number of elements in pup               */
+
+       /* Total length in bytes include blockid, ntot, version, as well
+          as the common block entries                                     */
+       *ntot = sizeof(int)*(5 + 2*nn + 2*nn2) + sizeof(double)*(4 + 2*nn + nn5);
+
+       if (xdrs->x_op == XDR_MCFIOCODE) return TRUE;
+       strncpy(version[0],stdver_.stdhep_ver, 4);
+       } 
+      
+     if     ( (xdr_int(xdrs, blockid) &&
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH) &&
+     	      xdr_int(xdrs, &(hepeup_.nup)) &&
+              xdr_int(xdrs, &(hepeup_.idprup))) == FALSE) return FALSE;
+              
+     if ((xdrs->x_op == XDR_DECODE) && ( *blockid != MCFIO_HEPEUP) ) {
+          fprintf (stderr, "mcf_hepup_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+     }
+
+     if ( xdr_double(xdrs, &(hepeup_.xwgtup) ) == FALSE) return FALSE;
+     if ( xdr_double(xdrs, &(hepeup_.scalup) ) == FALSE) return FALSE;
+     if ( xdr_double(xdrs, &(hepeup_.aqedup) ) == FALSE) return FALSE;
+     if ( xdr_double(xdrs, &(hepeup_.aqcdup) ) == FALSE) return FALSE;
+     idat = hepeup_.idup;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+         &nn, MAXNUP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = hepeup_.istup;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+         &nn, MAXNUP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = (int *) hepeup_.mothup;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+         &nn2, 2*MAXNUP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = (int *) hepeup_.icolup;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+         &nn2, 2*MAXNUP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     dat = (double *)  hepeup_.pup;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+         &nn5, 5*MAXNUP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     dat = (double *)  hepeup_.vtimup;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+         &nn, MAXNUP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     dat = (double *)  hepeup_.spinup;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+         &nn, MAXNUP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     return TRUE;
+}   
+
+bool_t xdr_heprup_(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version)
+
+{
+/*  Translate the HEPRUP COMMON block from the STDHEP package to/from
+    an XDR stream. Note that we do not allocate memory, because we fill
+    directly the COMMON.  Also, mcfio will allocate the space for the 
+    string version.        */
+    
+    unsigned int nn, n2;
+    int *idat;
+    double *dat;
+    
+    if ((xdrs->x_op == XDR_ENCODE) || (xdrs->x_op == XDR_MCFIOCODE))  {
+       if (*blockid != MCFIO_HEPRUP) {
+          fprintf (stderr, "mcf_hepup_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+       }
+
+       nn =  (unsigned int) heprup_.nprup;   /* Number of elements in xsecup, xerrup, xmaxup, lprup */
+       n2 =  (unsigned int) 2;   /* Number of elements in idbmup, ebmup, pdfgup, pdfsup */
+
+       /* Total length in bytes include blockid, ntot, version, as well
+          as the common block entries                                     */
+       *ntot = sizeof(int)*(5 + 3*n2 + nn) + sizeof(double)*(n2 + 3*nn);
+
+       if (xdrs->x_op == XDR_MCFIOCODE) return TRUE;
+       strncpy(version[0],stdver_.stdhep_ver, 4);
+       } 
+      
+     if     ( (xdr_int(xdrs, blockid) &&
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH) &&
+     	      xdr_int(xdrs, &(heprup_.idwtup)) &&
+              xdr_int(xdrs, &(heprup_.nprup))) == FALSE) return FALSE;
+              
+     if ((xdrs->x_op == XDR_DECODE) && ( *blockid != MCFIO_HEPRUP) ) {
+          fprintf (stderr, "mcf_hepup_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+     }
+     idat = heprup_.idbmup;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+            &n2, 2, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     dat = (double *)  heprup_.ebmup;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+                &n2, 2, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     idat = heprup_.pdfgup;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+            &n2, 2, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     idat = heprup_.pdfsup;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+            &n2, 2, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     dat = (double *)  heprup_.xsecup;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+                &nn, MAXPUP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     dat = (double *)  heprup_.xerrup;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+                &nn, MAXPUP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     dat = (double *)  heprup_.xmaxup;
+     if     ( xdr_array(xdrs,  (char **)   &dat,
+                &nn, MAXPUP, sizeof(double), (void *) xdr_double) == FALSE) return FALSE; 
+     idat = heprup_.lprup;
+     if     ( xdr_array(xdrs, (char **)  &idat,
+            &nn, MAXPUP, sizeof(int), (void *) xdr_int) == FALSE) return FALSE;
+     
+     return TRUE;
+}   
+
+
Index: /trunk/Utilities/stdhep/mcf_stdcm1_xdr.c
===================================================================
--- /trunk/Utilities/stdhep/mcf_stdcm1_xdr.c	(revision 3)
+++ /trunk/Utilities/stdhep/mcf_stdcm1_xdr.c	(revision 3)
@@ -0,0 +1,147 @@
+/*******************************************************************************
+*									       *
+* mcf_stdcm1_xdr.c -- XDR Utility routines for the Block stdcm1 filters        *
+*									       *
+* Copyright (c) 1994 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Paul Lebrun, Lynn Garren					       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <sys/types.h>
+#include <rpc/xdr.h>
+#include <limits.h>
+#ifdef SUNOS
+#include <floatingpoint.h>
+#else /* SUNOS */
+#include <float.h>
+#endif /* SUNOS */
+#include <stdlib.h>
+#include <time.h>
+#include "Utilities/mcfio/mcfio_Dict.h"
+#include "Utilities/mcfio/mcf_xdr.h"
+#include "Utilities/stdhep/stdcm1.h"
+#include "Utilities/stdhep/stdver.h"
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+extern struct stdver stdver_;
+extern struct stdcm1 stdcm1_;
+extern struct stdcm2 stdcm2_;
+
+bool_t xdr_stdhep_cm1_(XDR *xdrs, int *blockid,
+ 				 int *ntot, char** version)
+
+{
+/*  Translate the STDCM1 COMMON block from the STDHEP package to/from
+    an XDR stream. Note that we do not allocate memory, because we fill
+    directly the COMMON.  Also, mcfio will allocate the space for the 
+    string version.  */
+    
+    unsigned int nn, nn1, nn2;
+    char *vers;
+    char *cdat;
+    
+    if ((xdrs->x_op == XDR_ENCODE) || (xdrs->x_op == XDR_MCFIOCODE))  {
+       if (( *blockid != MCFIO_STDHEPEND)&&( *blockid != MCFIO_STDHEPBEG)) {
+          fprintf (stderr, "mcf_Stdhep_cm1_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+       }
+       nn = sizeof(int) * stdcm1_.nevtreq;
+       nn1 = sizeof(float) * stdcm1_.nevtreq;
+       nn2 = sizeof(double) * stdcm1_.nevtreq;
+       *ntot = 3 * sizeof(int) + 3 * nn + 2 * nn1 +  2 * nn2
+               + 2 * sizeof(char) * ( MCF_XDR_STDCM2_LENGTH + 1 );
+       if (xdrs->x_op == XDR_MCFIOCODE) return TRUE;
+       strncpy(version[0],stdver_.stdhep_ver, 4);
+     } 
+      
+     if     ( (xdr_int(xdrs, blockid) &&
+     	      xdr_int(xdrs, ntot) &&
+     	      xdr_string(xdrs, version, MCF_XDR_VERSION_LENGTH) )
+              == FALSE) return FALSE;
+              
+     if ((xdrs->x_op == XDR_DECODE) && 
+          (( *blockid != MCFIO_STDHEPEND)&&( *blockid != MCFIO_STDHEPBEG))) {
+          fprintf (stderr, "mcf_Stdhep_cm1_xdr: Inconsistent Blockid %d \n ", 
+           (*blockid));
+          return FALSE;
+     }
+     if ( xdr_int(xdrs, &(stdcm1_.nevtreq) ) == FALSE) return FALSE;
+     if ( xdr_int(xdrs, &(stdcm1_.nevtgen) ) == FALSE) return FALSE;
+     if ( xdr_int(xdrs, &(stdcm1_.nevtwrt) ) == FALSE) return FALSE;
+     if ( xdr_float(xdrs, &(stdcm1_.stdecom) ) == FALSE) return FALSE;
+     if ( xdr_float(xdrs, &(stdcm1_.stdxsec) ) == FALSE) return FALSE;
+     if ( xdr_double(xdrs, &(stdcm1_.stdseed1) ) == FALSE) return FALSE;
+     if ( xdr_double(xdrs, &(stdcm1_.stdseed2) ) == FALSE) return FALSE;
+     /*
+     ** V5.01 Upgrade : adding stdcm2 
+     */ 
+     vers = *version;          
+     if (((strcmp(vers,"1.") == 0) || (strcmp(vers,"2.") == 0) ||
+          (strcmp(vers,"3.") == 0) || (strcmp(vers,"4.") == 0) ||
+	  (strcmp(vers,"5.00") == 0) ) && (xdrs->x_op == XDR_DECODE)) {
+	   strncpy(stdcm2_.generatorname, " ", MCF_XDR_STDCM2_LENGTH);
+	   strncpy(stdcm2_.pdfname, " ", MCF_XDR_STDCM2_LENGTH);
+           return TRUE;
+     }
+/* 
+  allocate memory and deal with encoding and decoding separately
+*/
+     cdat = malloc(MCF_XDR_STDCM2_LENGTH+1);
+     if( (xdrs->x_op == XDR_DECODE) ) {
+	 strncpy(stdcm2_.generatorname, " ", MCF_XDR_STDCM2_LENGTH);
+	 strncpy(stdcm2_.pdfname, " ", MCF_XDR_STDCM2_LENGTH);
+	 cdat = NULL;
+	 if ( xdr_string(xdrs, &cdat, MCF_XDR_STDCM2_LENGTH+1 ) == FALSE) return FALSE;
+         strncpy(stdcm2_.generatorname,cdat,MCF_XDR_STDCM2_LENGTH);
+	 cdat = NULL;
+	 if ( xdr_string(xdrs, &cdat, MCF_XDR_STDCM2_LENGTH+1 ) == FALSE) return FALSE;
+         strncpy(stdcm2_.pdfname,cdat,MCF_XDR_STDCM2_LENGTH);
+     } else {
+	 strncpy(cdat, stdcm2_.generatorname, MCF_XDR_STDCM2_LENGTH);
+         /* some compilers do not properly append the null terminator */
+	 cdat[MCF_XDR_STDCM2_LENGTH]='\0';
+	 if ( xdr_string(xdrs, &cdat, MCF_XDR_STDCM2_LENGTH+1 ) == FALSE) return FALSE;
+	 strncpy(cdat, stdcm2_.pdfname, MCF_XDR_STDCM2_LENGTH);
+	 cdat[MCF_XDR_STDCM2_LENGTH]='\0';
+	 if ( xdr_string(xdrs, &cdat, MCF_XDR_STDCM2_LENGTH+1 ) == FALSE) return FALSE;
+     }
+     free(cdat);
+
+     /*
+     ** V5.02 Upgrade : add nevtlh to stdcm1 
+     ** note that we cannot get here unless the version is 5.00 or greater
+     */ 
+     if (((strcmp(vers,"5.00") == 0) || (strcmp(vers,"5.01") == 0))
+	  && (xdrs->x_op == XDR_DECODE)) {
+	   stdcm1_.nevtlh = 0;
+           return TRUE;
+     }
+     if ( xdr_int(xdrs, &(stdcm1_.nevtlh) ) == FALSE) return FALSE;
+
+     return TRUE;
+}   
+
Index: /trunk/Utilities/stdhep/stdcm1.h
===================================================================
--- /trunk/Utilities/stdhep/stdcm1.h	(revision 3)
+++ /trunk/Utilities/stdhep/stdcm1.h	(revision 3)
@@ -0,0 +1,19 @@
+/*
+** STDHEP begin/end run COMMON block
+** See product StDhep
+*/
+struct stdcm1 {
+float stdecom;   /*   STDECOM  - center-of-mass energy */
+float stdxsec;   /*   STDXSEC  - cross-section */
+double stdseed1; /*   STDSEED1 - random number seed */
+double stdseed2; /*   STDSEED2 - random number seed */
+int nevtreq;     /*   NEVTREQ  - number of events to be generated */
+int nevtgen;     /*   NEVTGEN  - number of events actually generated */
+int nevtwrt;     /*   NEVTWRT  - number of events written to output file */
+int nevtlh;      /*   NEVTLH  - number of Les Houches events written to output file */
+};
+
+struct stdcm2 {
+char generatorname[20];		/* name of Monte Carlo generator */
+char pdfname[20];     		/* name of PDF method used */
+};
Index: /trunk/Utilities/stdhep/stdcnt.h
===================================================================
--- /trunk/Utilities/stdhep/stdcnt.h	(revision 3)
+++ /trunk/Utilities/stdhep/stdcnt.h	(revision 3)
@@ -0,0 +1,9 @@
+/*
+    StdHep counting common block
+*/
+struct stdcnt {
+    int nstdwrt;	/* number of events written */
+    int nstdrd;		/* number of events read */
+    int nlhwrt;		/* number of Les Houches events written */
+    int nlhrd;		/* number of Les Houches events read */
+};
Index: /trunk/Utilities/stdhep/stdhd.h
===================================================================
--- /trunk/Utilities/stdhep/stdhd.h	(revision 3)
+++ /trunk/Utilities/stdhep/stdhd.h	(revision 3)
@@ -0,0 +1,19 @@
+/* 
+----------------------------------------------------------------
+   This header collects the mcfio initial information
+----------------------------------------------------------------
+*/
+
+struct stdhd1 {
+char date[255];		/* MCFIO_CREATIONDATE: creation date */
+char title[255];	/* MCFIO_TITLE: title */
+char comment[255];	/* MCFIO_COMMENT: comment */
+};
+
+struct stdhd2 {
+int dlen;         /* actual lenght of date */
+int tlen;         /* actual lenght of title */
+int clen;         /* actual lenght of comment */
+int numblocks;    /* MCFIO_NUMBLOCKS: number of blocks per event */
+int blkids[50];   /* MCFIO_BLOCKIDS: list of block types */
+};
Index: /trunk/Utilities/stdhep/stdhep.h
===================================================================
--- /trunk/Utilities/stdhep/stdhep.h	(revision 3)
+++ /trunk/Utilities/stdhep/stdhep.h	(revision 3)
@@ -0,0 +1,42 @@
+#ifndef STDHEP_H
+#define STDHEP_H
+/*
+** Basic COMMON block from STDHEP: the HEPEVT COMMON block 
+** See product StDhep
+*/
+/*  note that to avoid alignment problems, structures and common blocks
+    should be in the order: double precision, real, integer.
+*/
+
+#if defined(c_plusplus) || defined(__cplusplus)
+extern "C" {
+#endif
+
+#define NMXHEP 4000
+#define NMXMLT 16
+struct hepevt {
+int nevhep;		/* The event number */
+int nhep;		/* The number of entries in this event */
+int isthep[NMXHEP]; 	/* The Particle id */
+int idhep[NMXHEP];      /* The particle id */
+int jmohep[NMXHEP][2];    /* The position of the mother particle */
+int jdahep[NMXHEP][2];    /* Position of the first daughter... */
+double phep[NMXHEP][5];    /* 4-Momentum, mass */
+double vhep[NMXHEP][4];    /* Vertex information */
+};
+struct hepev2 {
+int nmulti;		/* number of interactions in the list */
+int jmulti[NMXHEP];     /* multiple interaction number */
+};
+struct hepev3 {
+int nevmulti[NMXMLT];     /* event number of original interaction */
+int itrkmulti[NMXMLT];     /* first particle in the original interaction */
+int mltstr[NMXMLT];     /* stream this event is from */
+};
+
+#if defined(c_plusplus) || defined(__cplusplus)
+}
+#endif
+
+#endif /* STDHEP_H */
+
Index: /trunk/Utilities/stdhep/stdhep_declarations.h
===================================================================
--- /trunk/Utilities/stdhep/stdhep_declarations.h	(revision 3)
+++ /trunk/Utilities/stdhep/stdhep_declarations.h	(revision 3)
@@ -0,0 +1,40 @@
+#ifndef STDHEP_DECLARATIONS_H
+#define STDHEP_DECLARATIONS_H
+
+/* declare the struct instances */
+
+#include "Utilities/stdhep/stdhep.h"
+#include "Utilities/stdhep/hepev4.h"
+#include "Utilities/stdhep/hepeup.h"
+#include "Utilities/stdhep/heprup.h"
+#include "Utilities/stdhep/stdtmp.h"
+#include "Utilities/stdhep/stdhd.h"
+#include "Utilities/stdhep/stdcnt.h"
+#include "Utilities/stdhep/stdcm1.h"
+#include "Utilities/stdhep/stdver.h"
+
+#if defined(c_plusplus) || defined(__cplusplus)
+extern "C" {
+#endif
+
+struct hepevt myhepevt;
+struct hepev2 hepev2_;
+struct hepev3 hepev3_;
+struct hepev4 hepev4_;
+struct hepev5 hepev5_;
+struct hepeup hepeup_;
+struct heprup heprup_;
+struct stdcnt stdcnt_;
+struct stdhd1 stdhd1_;
+struct stdhd2 stdhd2_;
+struct stdtmp stdtmp_;
+struct tmpev4 tmpev4_;
+struct stdcm1 stdcm1_;
+struct stdcm2 stdcm2_;
+struct stdver stdver_;
+
+#if defined(c_plusplus) || defined(__cplusplus)
+}
+#endif
+
+#endif /* STDHEP_DECLARATIONS_H */
Index: /trunk/Utilities/stdhep/stdhep_internal_utils.c
===================================================================
--- /trunk/Utilities/stdhep/stdhep_internal_utils.c	(revision 3)
+++ /trunk/Utilities/stdhep/stdhep_internal_utils.c	(revision 3)
@@ -0,0 +1,215 @@
+/*******************************************************************************
+*									       *
+* stdhep_internal_utils.c -- C version of stdhep internal utility routines     *
+*									       *
+* Copyright (c) 1995 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Lynn Garren    					       	       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+/* 
+*   StdHep definitions and include files
+*/
+#include "Utilities/stdhep/stdhep.h"
+#include "Utilities/stdhep/hepev4.h"
+#include "Utilities/stdhep/stdtmp.h"
+#include "Utilities/stdhep/hepeup.h"
+
+extern struct stdtmp stdtmp_;
+extern struct tmpev4 tmpev4_;
+
+extern struct hepevt myhepevt;
+extern struct hepev2 hepev2_;
+extern struct hepev3 hepev3_;
+extern struct hepev4 hepev4_;
+extern struct hepev5 hepev5_;
+extern struct hepeup hepeup_;
+
+/* Purpose: copy an event to/from the standard common block */
+int StdHepTempCopy(int idir, int istr)
+{
+    int nh, i, k;
+    if (idir == 1) {        /* copy from hepevt to stdtmp */
+        stdtmp_.nevhept = myhepevt.nevhep;
+        stdtmp_.nhept = myhepevt.nhep;
+	tmpev4_.eventweightt = hepev4_.eventweightlh;
+	tmpev4_.alphaqedt = hepev4_.alphaqedlh;
+	tmpev4_.alphaqcdt = hepev4_.alphaqcdlh;
+        for (i = 0; i < 10; i++) {
+	    tmpev4_.scalet[i] = hepev4_.scalelh[i];
+	}
+	tmpev4_.idrupt = hepev4_.idruplh;
+        for (i = 0; i < myhepevt.nhep; i++) {
+            stdtmp_.isthept[i] = myhepevt.isthep[i];
+            stdtmp_.idhept[i] = myhepevt.idhep[i];
+            for (k = 0; k < 2; k++) {
+                stdtmp_.jmohept[i][k] = myhepevt.jmohep[i][k];
+                stdtmp_.jdahept[i][k] = myhepevt.jdahep[i][k];
+		tmpev4_.icolorflowt[i][k] = hepev4_.icolorflowlh[i][k];
+                }
+            for (k = 0; k < 5; k++)
+                stdtmp_.phept[i][k] = myhepevt.phep[i][k];
+            for (k = 0; k < 4; k++)
+                stdtmp_.vhept[i][k] = myhepevt.vhep[i][k];
+            for (k = 0; k < 3; k++)
+                tmpev4_.spint[i][k] = hepev4_.spinlh[i][k];
+            }
+    } else if (idir == 2) {    /* copy from stdtmp to hepevt */
+        if (myhepevt.nhep + stdtmp_.nhept > NMXHEP) {
+            fprintf(stderr,
+              "     StdHepTempCopy: event would overflow HEPEVT array size\n");
+            fprintf(stderr,"     StdHepTempCopy: event %d has been lost\n",
+                   stdtmp_.nevhept);
+            return 5;
+            }
+        myhepevt.nevhep = stdtmp_.nevhept;
+        nh = myhepevt.nhep;
+	hepev4_.eventweightlh = tmpev4_.eventweightt;
+	hepev4_.alphaqedlh = tmpev4_.alphaqedt;
+	hepev4_.alphaqcdlh = tmpev4_.alphaqcdt;
+        for (i = 0; i < 10; i++) {
+	    hepev4_.scalelh[i] = tmpev4_.scalet[i];
+	}
+	hepev4_.idruplh = tmpev4_.idrupt;
+        for (i = 0; i < stdtmp_.nhept; i++) {
+            myhepevt.isthep[nh+i] = stdtmp_.isthept[i];
+            myhepevt.idhep[nh+i] = stdtmp_.idhept[i];
+            for (k = 0; k < 2; k++) {
+                myhepevt.jmohep[nh+i][k] = stdtmp_.jmohept[i][k];
+                myhepevt.jdahep[nh+i][k] = stdtmp_.jdahept[i][k];
+		hepev4_.icolorflowlh[nh+i][k] = tmpev4_.icolorflowt[i][k];
+                }
+            for (k = 0; k < 5; k++)
+                myhepevt.phep[nh+i][k] = stdtmp_.phept[i][k];
+            for (k = 0; k < 4; k++)
+                myhepevt.vhep[nh+i][k] = stdtmp_.vhept[i][k];
+            for (k = 0; k < 3; k++)
+                hepev4_.spinlh[nh+i][k] = tmpev4_.spint[i][k];
+            }
+        hepev2_.nmulti += 1;
+	if (hepev2_.nmulti <= NMXMLT ) {
+	    hepev3_.nevmulti[hepev2_.nmulti] = stdtmp_.nevhept;
+	    hepev3_.itrkmulti[hepev2_.nmulti] = stdtmp_.nhept + 1;
+	    hepev3_.mltstr[hepev2_.nmulti] = istr;
+	    hepev5_.eventweightmulti[i] = tmpev4_.eventweightt;
+	    hepev5_.alphaqedmulti[i] = tmpev4_.alphaqedt;
+	    hepev5_.alphaqcdmulti[i] = tmpev4_.alphaqcdt;
+	    for( k = 0; k < 10; ++k) {
+		hepev5_.scalemulti[i][k] = tmpev4_.scalet[k];
+	    }
+	    hepev5_.idrupmulti[i] = tmpev4_.idrupt;
+	} else {
+	    fprintf(stderr," StdHepTempCopy: %d multiple interactions in this event\n",
+	         hepev2_.nmulti );  
+	    fprintf(stderr," StdHepTempCopy: only %d multiple interactions are allowed\n",
+	         NMXMLT );  
+	}
+        for (i = 0; i < stdtmp_.nhept; i++) {
+            hepev2_.jmulti[nh+i] = hepev2_.nmulti;
+            for (k = 0; k < 2; k++) {
+                if (myhepevt.jmohep[nh+i][k] != 0) {
+		   myhepevt.jmohep[nh+i][k] += myhepevt.nhep;
+		   }
+                if (myhepevt.jdahep[nh+i][k] != 0) {
+		   myhepevt.jdahep[nh+i][k] += myhepevt.nhep;
+		   }
+                if (hepev4_.icolorflowlh[nh+i][k] != 0) {
+		   hepev4_.icolorflowlh[nh+i][k] += myhepevt.nhep;
+		   }
+                }
+        }
+        myhepevt.nhep += stdtmp_.nhept;
+    } else {
+        fprintf(stderr," StdHepTempCopy: improper calling flag\n");
+    }
+    return 0;
+}
+
+void StdHepZero(void)
+{
+    int i, k;
+    myhepevt.nhep = 0;
+    hepev2_.nmulti = 0;
+    for (i = 0; i < NMXHEP; i++) {
+        myhepevt.isthep[i] = 0;
+        myhepevt.idhep[i] = 0;
+        hepev2_.jmulti[i] = 0;
+        for (k = 0; k < 2; k++) {
+            myhepevt.jmohep[i][k] = 0;
+            myhepevt.jdahep[i][k] = 0;
+	    hepev4_.icolorflowlh[i][k] = 0;
+            }
+        for (k = 0; k < 5; k++)
+            myhepevt.phep[i][k] = 0.;
+        for (k = 0; k < 4; k++)
+            myhepevt.vhep[i][k] = 0.;
+        for (k = 0; k < 3; k++)
+            hepev4_.spinlh[i][k] = 0.;
+        }
+    for (i = 0; i < NMXMLT; i++) {
+        hepev3_.nevmulti[i] = 0;
+        hepev3_.itrkmulti[i] = 0;
+        hepev3_.mltstr[i] = 0;
+	hepev5_.eventweightmulti[i] = 0.;
+	hepev5_.alphaqedmulti[i] = 0.;
+	hepev5_.alphaqcdmulti[i] = 0.;
+	for( k = 0; k < 10; ++k) {
+	    hepev5_.scalemulti[i][k] = 0.;
+	}
+	hepev5_.idrupmulti[i] = 0;
+    }
+    hepev4_.eventweightlh = 0.;
+    hepev4_.alphaqedlh = 0.;
+    hepev4_.alphaqcdlh = 0.;
+    for (i = 0; i < 10; i++) {
+        hepev4_.scalelh[i] = 0.;
+    }
+    hepev4_.idruplh = 0;
+}
+
+void StdHepZeroHEPEUP(void)
+{
+   int i, k;
+   hepeup_.nup = 0;
+   hepeup_.idprup = 0;
+   hepeup_.xwgtup = 0;
+   hepeup_.scalup = 0;
+   hepeup_.aqedup = 0;
+   hepeup_.aqcdup = 0;
+   for (i = 0; i < MAXNUP; ++i) {
+      hepeup_.idup[i] = 0;
+      hepeup_.istup[i] = 0;
+      for (k = 0; k < 2; ++k) {
+         hepeup_.mothup[i][k] = 0;
+         hepeup_.icolup[i][k] = 0;
+      }
+      for (k = 0; k < 5; ++k) {
+         hepeup_.pup[i][k] = 0;
+      }
+      hepeup_.vtimup[i] = 0;
+      hepeup_.spinup[i] = 0;
+   }
+}
Index: /trunk/Utilities/stdhep/stdhep_mcfio.c
===================================================================
--- /trunk/Utilities/stdhep/stdhep_mcfio.c	(revision 3)
+++ /trunk/Utilities/stdhep/stdhep_mcfio.c	(revision 3)
@@ -0,0 +1,563 @@
+/*******************************************************************************
+*									       *
+* stdhep_mcfio.c -- C version of mcfio interface routines                      *
+*									       *
+* Copyright (c) 1995 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Lynn Garren    					       	       *
+*									       *
+*									       *
+*******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+/* 
+*   mcfio/StdHep definitions and include files
+*/
+#include "Utilities/mcfio/mcf_xdr.h"
+#include "Utilities/mcfio/mcfio_Block.h"
+#include "Utilities/mcfio/mcfio_Dict.h"
+#include "Utilities/mcfio/mcfio_Direct.h"
+#include "Utilities/mcfio/mcfio_Util1.h"
+#include "Utilities/stdhep/stdhep.h"
+#include "Utilities/stdhep/hepev4.h"
+#include "Utilities/stdhep/hepeup.h"
+#include "Utilities/stdhep/heprup.h"
+#include "Utilities/stdhep/stdtmp.h"
+#include "Utilities/stdhep/stdhd.h"
+#include "Utilities/stdhep/stdcnt.h"
+#include "Utilities/stdhep/stdhep_mcfio.h"
+
+#define LUN_ARRAY 16	/* I/O array size */
+struct stdstr {
+    int ixdrstr[LUN_ARRAY];	/* array of xdr stream addresses */
+} stdstr_;
+
+/* extern struct hepevt hepevt_; */
+extern struct hepevt myhepevt;
+extern struct hepev2 hepev2_;
+extern struct hepev3 hepev3_;
+extern struct hepev4 hepev4_;
+extern struct hepev5 hepev5_;
+extern struct hepeup hepeup_;
+extern struct heprup heprup_;
+extern struct stdcnt stdcnt_;
+extern struct stdhd1 stdhd1_;
+extern struct stdhd2 stdhd2_;
+extern struct stdtmp stdtmp_;
+extern struct tmpev4 tmpev4_;
+
+extern int xdr_stdhep_();
+extern int xdr_stdhep_multi_();
+extern int xdr_stdhep_4_();
+extern int xdr_stdhep_4_multi_();
+extern int xdr_stdhep_cm1_();
+extern int xdr_hepeup_();
+extern int xdr_heprup_();
+
+int StdHepXdrReadInit(char *filename, int *ntries, int ist)
+{
+    int ierr;
+    
+    mcfioC_Init();
+    ierr = StdHepXdrReadOpen(filename, ntries, ist);
+    return ierr;
+}
+int StdHepXdrReadOpen(char *filename, int *ntries, int ist)
+{
+    int istream, iblk;
+    int numblocks, blkids[50];
+
+    istream =  mcfioC_OpenReadDirect(filename);
+    stdstr_.ixdrstr[ist] = istream;
+    if (istream == -1) {
+        fprintf(stderr," StdHepXdrReadOpen: cannot open output file \n");
+        return -1;
+        }
+    mcfioC_InfoStreamChar(istream, MCFIO_CREATIONDATE, stdhd1_.date, &stdhd2_.dlen);
+    mcfioC_InfoStreamChar(istream, MCFIO_TITLE, stdhd1_.title, &stdhd2_.tlen);
+    mcfioC_InfoStreamChar(istream, MCFIO_COMMENT, stdhd1_.comment, &stdhd2_.clen);
+    mcfioC_InfoStreamInt(istream, MCFIO_NUMEVTS, ntries);
+    mcfioC_InfoStreamInt(istream, MCFIO_NUMBLOCKS, &numblocks);
+    mcfioC_InfoStreamInt(istream, MCFIO_BLOCKIDS, blkids);
+
+    stdhd2_.numblocks = numblocks; 
+    for ( iblk=0; iblk < numblocks; ++iblk ) {
+        stdhd2_.blkids[iblk] = blkids[iblk];
+    }
+
+    stdcnt_.nstdrd = 0;
+    stdcnt_.nlhrd = 0;
+/*
+    fprintf(stdout,
+       " StdHepXdrReadOpen: successfully opened input stream %d\n", istream);
+    fprintf(stdout,"          title: %s\n", stdhd1_.title);
+    fprintf(stdout,"          date: %s\n", stdhd1_.date);
+    fprintf(stdout,"                    %d events\n", *ntries);
+    fprintf(stdout,"                    %d blocks per event\n", stdhd2_.numblocks);
+*/
+    return 0;
+}
+int StdHepXdrRead(int *ilbl, int ist)
+{
+/* Purpose: to read a buffer or an event from the standard common block.
+C
+C       returns ilbl
+C
+C		ilbl = 1   - standard HEPEVT common block
+C		ilbl = 2   - standard HEPEVT common block and HEPEV2
+C		ilbl = 3   - stdevent struct
+C	        ilbl = 4   - standard HEPEVT common block with Les Houches
+C	        ilbl = 5   - standard HEPEVT common block with Les Houches
+C                               and multiple collisions
+C		ilbl = 11  -  HEPEUP common block
+C		ilbl = 12  -  HEPRUP common block
+C		ilbl = 100 - STDHEP begin run record
+C		ilbl = 200 - STDHEP end run record
+C   */
+
+    int istat;
+    int istream;
+    int i, numblocks, blkids[50];
+
+    istream = stdstr_.ixdrstr[ist];
+    if(mcfioC_NextEvent(istream) != MCFIO_RUNNING) {
+        mcfioC_InfoStreamInt(istream, MCFIO_STATUS, &istat);
+        if(istat == MCFIO_EOF) {
+            fprintf(stderr,"     StdHepXdrRead: end of file found\n");
+            return 1;
+            }
+        else {
+            fprintf(stderr,"     StdHepXdrRead: unrecognized status - stop\n");
+            return 2;
+            }
+        }
+    mcfioC_InfoStreamInt(istream, MCFIO_NUMBLOCKS, &numblocks);
+    mcfioC_InfoStreamInt(istream, MCFIO_BLOCKIDS, blkids);
+
+    for (i = 0; i < numblocks; i++) {
+        if (blkids[i] == MCFIO_STDHEP) {
+            StdHepZero();
+            if (mcfioC_Block(istream,MCFIO_STDHEP,xdr_stdhep_) != -1) {
+                *ilbl = 1;
+                if (StdHepTempCopy(2,istream) == 0)
+                    stdcnt_.nstdrd = stdcnt_.nstdrd + 1;
+                return 0;
+                }
+            }
+        else if (blkids[i] == MCFIO_STDHEPM) {
+            StdHepZero();
+            if (mcfioC_Block(istream,MCFIO_STDHEPM,xdr_stdhep_multi_) != -1) {
+                *ilbl = 2;
+                stdcnt_.nstdrd = stdcnt_.nstdrd + 1;
+                return 0;
+                }
+            }
+        else if (blkids[i] == MCFIO_STDHEP4) {
+            StdHepZero();
+            if (mcfioC_Block(istream,MCFIO_STDHEP4,xdr_stdhep_4_) != -1) {
+                *ilbl = 4;
+                if (StdHepTempCopy(2,istream) == 0)
+                    stdcnt_.nstdrd = stdcnt_.nstdrd + 1;
+                return 0;
+                }
+            }
+        else if (blkids[i] == MCFIO_STDHEP4M) {
+            StdHepZero();
+            if (mcfioC_Block(istream,MCFIO_STDHEP4M,xdr_stdhep_4_multi_) != -1) {
+                *ilbl = 5;
+                stdcnt_.nstdrd = stdcnt_.nstdrd + 1;
+                return 0;
+                }
+            }
+        else if (blkids[i] == MCFIO_STDHEPBEG) {
+            if (mcfioC_Block(istream,MCFIO_STDHEPBEG,xdr_stdhep_cm1_) != -1) {
+                *ilbl = 100;
+                return 0;
+                }
+            }
+        else if (blkids[i] == MCFIO_STDHEPEND) {
+            if (mcfioC_Block(istream,MCFIO_STDHEPEND,xdr_stdhep_cm1_) != -1) {
+                *ilbl = 200;
+                return 0;
+                }
+            }
+        else if (blkids[i] == MCFIO_HEPEUP) {
+            if (mcfioC_Block(istream,MCFIO_HEPEUP,xdr_hepeup_) != -1) {
+                *ilbl = 11;
+                stdcnt_.nlhrd = stdcnt_.nlhrd + 1;
+                return 0;
+                }
+            }
+        else if (blkids[i] == MCFIO_HEPRUP) {
+            if (mcfioC_Block(istream,MCFIO_HEPRUP,xdr_heprup_) != -1) {
+                *ilbl = 12;
+                stdcnt_.nlhrd = stdcnt_.nlhrd + 1;
+                return 0;
+                }
+            }
+        }
+    return 1;
+}
+int StdHepXdrReadMulti(int *ilbl, int ist)
+{
+/* Purpose: to read a buffer or an event from the standard common block
+            this routine handles multiple input streams
+C
+C       return ilbl
+C
+C		ilbl = 1   - standard HEPEVT common block
+C		ilbl = 2   - standard HEPEVT common block and HEPEV2
+C		ilbl = 100 - STDHEP begin run record
+C		ilbl = 200 - STDHEP end run record
+C   */
+
+    int istat;
+    int istream;
+    int i, numblocks, blkids[50];
+
+    istream = stdstr_.ixdrstr[ist];
+    if(mcfioC_NextEvent(istream) != MCFIO_RUNNING) {
+        mcfioC_InfoStreamInt(istream, MCFIO_STATUS, &istat);
+        if(istat == MCFIO_EOF) {
+            fprintf(stderr,"     StdHepXdrReadMulti: end of file found\n");
+            return 1;
+            }
+        else {
+            fprintf(stderr,
+              "     StdHepXdrReadMulti: unrecognized status - stop\n");
+            return 2;
+            }
+        }
+    mcfioC_InfoStreamInt(istream, MCFIO_NUMBLOCKS, &numblocks);
+    mcfioC_InfoStreamInt(istream, MCFIO_BLOCKIDS, blkids);
+    for (i = 0; i < numblocks; i++) {
+        if (blkids[i] == MCFIO_STDHEP) {
+           if (mcfioC_Block(istream,MCFIO_STDHEP,xdr_stdhep_) == -1) {
+                fprintf(stderr,
+                  "     StdHepXdrReadMulti: unable to read xdr block\n");
+                return 1;
+                }
+            *ilbl = 1;
+            if (StdHepTempCopy(2,istream) == 0)
+                stdcnt_.nstdrd = stdcnt_.nstdrd + 1;
+            }
+        else if (blkids[i] == MCFIO_STDHEPM) {
+            fprintf(stderr,
+          "    StdHepXdrRead: multiple interaction event - HEPEVT is zeroed\n");
+            StdHepZero();
+            if (mcfioC_Block(istream,MCFIO_STDHEPM,xdr_stdhep_multi_) == -1) {
+                fprintf(stderr,
+                  "     StdHepXdrReadMulti: unable to read xdr block\n");
+                return 1;
+                }
+            *ilbl = 2;
+            stdcnt_.nstdrd = stdcnt_.nstdrd + 1;
+            }
+        else if (blkids[i] == MCFIO_STDHEP4) {
+           if (mcfioC_Block(istream,MCFIO_STDHEP4,xdr_stdhep_4_) == -1) {
+                fprintf(stderr,
+                  "     StdHepXdrReadMulti: unable to read xdr block\n");
+                return 1;
+                }
+            *ilbl = 4;
+            if (StdHepTempCopy(2,istream) == 0)
+                stdcnt_.nstdrd = stdcnt_.nstdrd + 1;
+            }
+        else if (blkids[i] == MCFIO_STDHEP4M) {
+            fprintf(stderr,
+          "    StdHepXdrRead: multiple interaction event - HEPEVT is zeroed\n");
+            StdHepZero();
+            if (mcfioC_Block(istream,MCFIO_STDHEP4M,xdr_stdhep_4_multi_) == -1) {
+                fprintf(stderr,
+                  "     StdHepXdrReadMulti: unable to read xdr block\n");
+                return 1;
+                }
+            *ilbl = 5;
+            stdcnt_.nstdrd = stdcnt_.nstdrd + 1;
+            }
+        }
+    return 0;
+}
+int StdHepXdrWriteInit(char *filename, char *title, int ntries, int ist)
+{
+    int ierr;
+
+    mcfioC_Init();
+    ierr = StdHepXdrWriteOpen(filename, title, ntries, ist);
+    return ierr;
+}
+int StdHepXdrWriteOpen(char *filename, char *title, int ntries, int ist)
+{
+    int istream, iblk;
+    int numblocks = 8;
+    int blkids[50];
+    char *comment = '\0';
+
+    blkids[0] = MCFIO_STDHEP;
+    blkids[1] = MCFIO_STDHEPM;
+    blkids[2] = MCFIO_STDHEPBEG;
+    blkids[3] = MCFIO_STDHEPEND;
+    blkids[4] = MCFIO_STDHEP4;
+    blkids[5] = MCFIO_STDHEP4M;
+    blkids[6] = MCFIO_HEPEUP;
+    blkids[7] = MCFIO_HEPRUP;
+
+    strncpy(stdhd1_.title,title,255);
+    stdhd2_.numblocks = numblocks;
+    for ( iblk=0; iblk < numblocks; ++iblk ) {
+        stdhd2_.blkids[iblk] = blkids[iblk];
+    }
+ 
+    istream =  mcfioC_OpenWriteDirect(filename, title, comment,
+                    ntries, blkids, numblocks);
+    stdstr_.ixdrstr[ist] = istream;
+    if (istream == -1) {
+        fprintf(stderr," StdHepXdrWriteOpen: cannot open output file \n");
+        return -1;
+        }
+    fprintf(stdout," StdHepXdrWriteOpen: I/O initialized for StdHep only\n");
+    return 0;
+}
+int StdHepXdrWrite(int ilbl, int ist)
+{
+    int iret = 0;
+
+    if ((ilbl == 1) || (ilbl == 2))
+        iret = StdHepXdrWriteEvent(ilbl, ist);
+    else if ((ilbl == 4) || (ilbl == 5))
+        iret = StdHepXdrWriteEventLH(ilbl, ist);
+    else if (ilbl == 11) 
+        iret = StdHepXdrWriteEventEUP(ilbl, ist);
+    else if (ilbl == 12)
+        iret = StdHepXdrWriteEventRUP(ilbl, ist);
+    else if ((ilbl == 100) || (ilbl == 200))
+        iret = StdHepXdrWriteCM(ilbl, ist);
+    else
+        fprintf(stderr,
+      "     StdHepXdrWrite: don't know what to do with record type %d\n", ilbl);
+    return iret;
+}
+int StdHepXdrWriteCM(int ilbl, int ist)
+{
+    int istream;
+
+    istream = stdstr_.ixdrstr[ist];
+    if (ilbl == 100) {
+        if (mcfioC_Block(istream, MCFIO_STDHEPBEG, xdr_stdhep_cm1_) == -1) {
+            fprintf(stderr,
+              "     StdHepXdrWriteCM: error filling stdhep cm1 common block\n");
+            return 2;
+            }
+        }
+    else if (ilbl == 200) {
+        if (mcfioC_Block(istream, MCFIO_STDHEPEND, xdr_stdhep_cm1_) == -1) {
+            fprintf(stderr,
+              "     StdHepXdrWriteCM: error filling stdhep cm1 common block\n");
+            return 2;
+            }
+        }
+    else {
+        fprintf(stderr,
+           "     StdHepXdrWriteCM: called with improper label %d\n",ilbl);
+        return 3;
+        }
+    if (mcfioC_NextEvent(istream) == -1) {
+        fprintf(stderr,
+          "     StdHepXdrWriteCM: error writing stdhep cm1 xdr block\n");
+        return 1;
+        }
+    return 0;
+}
+int StdHepXdrWriteEvent(int ilbl, int ist)
+{
+    int istream;
+
+    istream = stdstr_.ixdrstr[ist];
+    if ((ilbl != 1) && (ilbl != 2)) {
+        fprintf(stderr,
+          "     StdHepXdrWriteEvent: called with illegal label %d\n",
+                            ilbl);
+        return 3;
+        }
+    else if (myhepevt.nhep <= 0) {
+        fprintf(stderr,
+          "     StdHepXdrWriteEvent: event %d is empty\n", myhepevt.nevhep);
+        return 0;
+        }
+    else if (ilbl == 1) {
+        if (StdHepTempCopy(1,istream) != 0) {
+            fprintf(stderr,
+              "     StdHepXdrWriteEvent: copy failed - event not written\n");
+            return 4;
+            }
+        if (mcfioC_Block(istream, MCFIO_STDHEP, xdr_stdhep_) == -1) {
+            fprintf(stderr,
+          "     StdHepXdrWriteEvent: error filling stdhep block for event %d\n",
+                     myhepevt.nevhep);
+            return 2;
+            }
+        mcfioC_SetEventInfo(istream, MCFIO_STORENUMBER, &myhepevt.nevhep);
+        }
+    else if (ilbl == 2) {
+        if (mcfioC_Block(istream, MCFIO_STDHEPM, xdr_stdhep_multi_) == -1) {
+            fprintf(stderr,
+          "     StdHepXdrWriteEvent: error filling stdhep block for event %d\n",
+                     myhepevt.nevhep);
+            return 2;
+            }
+        mcfioC_SetEventInfo(istream, MCFIO_STORENUMBER, &myhepevt.nevhep);
+        }
+    if (mcfioC_NextEvent(istream) == -1) {
+        fprintf(stderr,"     StdHepXdrWriteCM: error writing event %d\n",
+                         myhepevt.nevhep);
+        return 1;
+        }
+    stdcnt_.nstdwrt = stdcnt_.nstdwrt + 1;
+    return 0;
+}
+int StdHepXdrWriteEventLH(int ilbl, int ist)
+{
+    int istream;
+
+    istream = stdstr_.ixdrstr[ist];
+    if ((ilbl != 4) && (ilbl != 5)) {
+        fprintf(stderr,
+          "     StdHepXdrWriteEventLH: called with illegal label %d\n",
+                            ilbl);
+        return 3;
+        }
+    else if (myhepevt.nhep <= 0) {
+        fprintf(stderr,
+          "     StdHepXdrWriteEventLH: event %d is empty\n", myhepevt.nevhep);
+        return 0;
+        }
+    else if (ilbl == 4) {
+        if (StdHepTempCopy(1,istream) != 0) {
+            fprintf(stderr,
+              "     StdHepXdrWriteEventLH: copy failed - event not written\n");
+            return 4;
+            }
+        if (mcfioC_Block(istream, MCFIO_STDHEP4, xdr_stdhep_4_) == -1) {
+            fprintf(stderr,
+          "     StdHepXdrWriteEventLH: error filling stdhep block for event %d\n",
+                     myhepevt.nevhep);
+            return 2;
+            }
+        mcfioC_SetEventInfo(istream, MCFIO_STORENUMBER, &myhepevt.nevhep);
+        }
+    else if (ilbl == 5) {
+        if (mcfioC_Block(istream, MCFIO_STDHEP4M, xdr_stdhep_4_multi_) == -1) {
+            fprintf(stderr,
+          "     StdHepXdrWriteEventLH: error filling stdhep block for event %d\n",
+                     myhepevt.nevhep);
+            return 2;
+            }
+        mcfioC_SetEventInfo(istream, MCFIO_STORENUMBER, &myhepevt.nevhep);
+        }
+    if (mcfioC_NextEvent(istream) == -1) {
+        fprintf(stderr,"     StdHepXdrWriteLH: error writing event %d\n",
+                         myhepevt.nevhep);
+        return 1;
+        }
+    stdcnt_.nstdwrt = stdcnt_.nstdwrt + 1;
+    return 0;
+}
+int StdHepXdrWriteEventEUP(int ilbl, int ist)
+{
+    int istream;
+
+    istream = stdstr_.ixdrstr[ist];
+    if ( ilbl != 11 ) {
+        fprintf(stderr,
+          "     StdHepXdrWriteEventEUP: called with illegal label %d\n",
+                            ilbl);
+        return 3;
+        }
+    else if (hepeup_.nup <= 0) {
+        fprintf(stderr,
+          "     StdHepXdrWriteEventEUP: event is empty\n");
+        return 0;
+        }
+    else if (ilbl == 11) {
+        if (mcfioC_Block(istream, MCFIO_HEPEUP, xdr_hepeup_) == -1) {
+            fprintf(stderr,
+          "     StdHepXdrWriteEventEUP: error filling stdhep block for event\n");
+            return 2;
+            }
+        }
+    if (mcfioC_NextEvent(istream) == -1) {
+        fprintf(stderr,"     StdHepXdrWriteEUP: error writing event\n");
+        return 1;
+        }
+    stdcnt_.nlhwrt = stdcnt_.nlhwrt + 1;
+    return 0;
+}
+int StdHepXdrWriteEventRUP(int ilbl, int ist)
+{
+    int istream;
+
+    istream = stdstr_.ixdrstr[ist];
+    if ( ilbl != 12 ) {
+        fprintf(stderr,
+          "     StdHepXdrWriteEventRUP: called with illegal label %d\n",
+                            ilbl);
+        return 3;
+        }
+    else if (ilbl == 12) {
+        if (mcfioC_Block(istream, MCFIO_HEPRUP, xdr_heprup_) == -1) {
+            fprintf(stderr,
+          "     StdHepXdrWriteEventRUP: error filling stdhep block for event\n");
+            return 2;
+            }
+        }
+    if (mcfioC_NextEvent(istream) == -1) {
+        fprintf(stderr,"     StdHepXdrWriteRUP: error writing event\n");
+        return 1;
+        }
+    stdcnt_.nlhwrt = stdcnt_.nlhwrt + 1;
+    return 0;
+}
+void StdHepXdrEnd(int ist)
+{
+    int istream;
+    int inum, ieff;
+
+    istream = stdstr_.ixdrstr[ist];
+    mcfioC_InfoStreamInt(istream, MCFIO_NUMWORDS, &inum);
+    mcfioC_InfoStreamInt(istream, MCFIO_EFFICIENCY, &ieff);
+    mcfioC_Close(istream);
+/*
+    fprintf(stdout,
+       "          StdHepXdrEnd: %d words i/o with %d efficiency\n",inum,ieff);
+*/
+}
+void StdHepPrintHeader( )
+{
+    fprintf(stdout," StdHep MCFio header information:\n");
+    fprintf(stdout,"          title: %s\n",stdhd1_.title);
+    fprintf(stdout,"          date:  %s\n",stdhd1_.date);
+    fprintf(stdout,"          %s\n",stdhd1_.comment);
+    fprintf(stdout,"                    %d blocks per event\n",stdhd2_.numblocks);
+}
Index: /trunk/Utilities/stdhep/stdhep_mcfio.h
===================================================================
--- /trunk/Utilities/stdhep/stdhep_mcfio.h	(revision 3)
+++ /trunk/Utilities/stdhep/stdhep_mcfio.h	(revision 3)
@@ -0,0 +1,53 @@
+#ifndef STDHEP_MCFIO_H
+#define STDHEP_MCFIO_H
+
+/*******************************************************************************
+*									       *
+* stdhep_mcfio.h -- header for C version of mcfio interface routines                      *
+*									       *
+* Copyright (c) 1995 Universities Research Association, Inc.		       *
+* All rights reserved.							       *
+* 									       *
+* This material resulted from work developed under a Government Contract and   *
+* is subject to the following license:  The Government retains a paid-up,      *
+* nonexclusive, irrevocable worldwide license to reproduce, prepare derivative *
+* works, perform publicly and display publicly by or for the Government,       *
+* including the right to distribute to other Government contractors.  Neither  *
+* the United States nor the United States Department of Energy, nor any of     *
+* their employees, makes any warranty, express or implied, or assumes any      *
+* legal liability or responsibility for the accuracy, completeness, or         *
+* usefulness of any information, apparatus, product, or process disclosed, or  *
+* represents that its use would not infringe privately owned rights.           *
+*                                        				       *
+*									       *
+* Written by Lynn Garren    					       	       *
+*									       *
+*									       *
+*******************************************************************************/
+
+/*   prototypes */
+#if defined(c_plusplus) || defined(__cplusplus)
+extern "C" {
+#endif
+
+
+int StdHepXdrReadInit(char *filename, int *ntries, int ist);
+int StdHepXdrReadOpen(char *filename, int *ntries, int ist);
+int StdHepXdrRead(int *ilbl, int ist);
+int StdHepXdrReadMulti(int *ilbl, int ist);
+int StdHepXdrWriteInit(char *filename, char *title, int ntries, int ist);
+int StdHepXdrWriteOpen(char *filename, char *title, int ntries, int ist);
+int StdHepXdrWrite(int ilbl, int ist);
+int StdHepXdrWriteCM(int ilbl, int ist);
+int StdHepXdrWriteEvent(int ilbl, int ist);
+int StdHepXdrWriteEventLH(int ilbl, int ist);
+int StdHepXdrWriteEventEUP(int ilbl, int ist);
+int StdHepXdrWriteEventRUP(int ilbl, int ist);
+void StdHepXdrEnd(int ist);
+void StdHepPrintHeader( );
+
+#if defined(c_plusplus) || defined(__cplusplus)
+}
+#endif
+
+#endif /* STDHEP_MCFIO_H */
Index: /trunk/Utilities/stdhep/stdtmp.h
===================================================================
--- /trunk/Utilities/stdhep/stdtmp.h	(revision 3)
+++ /trunk/Utilities/stdhep/stdtmp.h	(revision 3)
@@ -0,0 +1,27 @@
+/*
+** Basic COMMON block from STDHEP: the temporary COMMON block
+** This is a copy of the HEPEVT COMMON block
+*/
+/*  note that to avoid alignment problems, structures and common blocks
+    should be in the order: double precision, real, integer.
+*/
+struct stdtmp {
+double phept[NMXHEP][5];    /* 4-Momentum, mass */
+double vhept[NMXHEP][4];    /* Vertex information */
+int nevhept;		/* The event number */
+int nhept;		/* The number of entries in this event */
+int isthept[NMXHEP]; 	/* The Particle id */
+int idhept[NMXHEP];      /* The particle id */
+int jmohept[NMXHEP][2];    /* The position of the mother particle */
+int jdahept[NMXHEP][2];    /* Position of the first daughter... */
+};
+
+struct tmpev4 {
+  double eventweightt;			/* event weight */
+  double alphaqedt; 			/* QED coupling alpha_em */
+  double alphaqcdt;			/* QCD coupling alpha_s */
+  double scalet[10]; 			/* Scale Q of the event */
+  double spint[NMXHEP][3]; 		/* spin information */
+  int    icolorflowt[NMXHEP][2]; 	/* (Anti-)Colour flow */
+  int    idrupt;			/* ID, as given by LPRUP codes */
+};
Index: /trunk/Utilities/stdhep/stdver.h
===================================================================
--- /trunk/Utilities/stdhep/stdver.h	(revision 3)
+++ /trunk/Utilities/stdhep/stdver.h	(revision 3)
@@ -0,0 +1,5 @@
+/*   stdhep version common block */
+struct stdver {
+char stdhep_ver[10];      /* stdhep version numver */
+char stdhep_date[20];     /* date of this stdhep version */
+};
