Skip to content
Snippets Groups Projects
  • sergeizharko's avatar
    f90e27f6
    COMMIT FROM 23.12.2021 · f90e27f6
    sergeizharko authored
      - cbmroot/reco/L1/L1Algo/L1BaseStationInfo.h:
        > a prototype of user-friendly interface to L1Station and other geometry inputs to L1Algo (experimental)
        > added setters and getters for L1Station data fields
        > added calculation of hidden L1Station properties
        > added Print() method
      - cbmroot/reco/L1/L1Algo/L1Parameters.h:
        > add new compile time constants: kMaxNFieldApproxCoefficients, kStationBits, kThreadBits, kTripletBits,
          kMaxNstations, kMaxNthreads, kMaxNtriplets
        > add new runtime "constants": fMaxDoubletsPerSinglet, fMaxTripletPerDoublets
        > add Print() method
      - cbmroot/reco/L1/L1Algo/L1Algo.h:
        > modifications according to the constants transfer to the L1Parameters class (example: fkMaxNthreads ==> L1Parameters::kMaxNthreads)
      - cbmroot/reco/L1/L1Algo/L1Algo.cxx:
        > add L1Parameters::Print() call from L1Algo::Init()
        > modifications according to the constants transfer to the L1Parameters class (example: fkMaxNthreads ==> L1Parameters::kMaxNthreads)
      - cbmroot/reco/L1/L1Algo/L1CATrackFinder.cxx:
        > modifications according to the constants transfer to the L1Parameters class (example: fkMaxNthreads ==> L1Parameters::kMaxNthreads)
      - cbmroot/reco/L1/L1Algo/L1TrackFitter.cxx:
        > modifications according to the constants transfer to the L1Parameters class (example: fkMaxNthreads ==> L1Parameters::kMaxNthreads)
      - cbmroot/reco/L1/L1Algo/L1Field.h:
        > magic constant '21' changed to L1Parameters::kMaxNFieldApproxCoefficients (compile time)
      - cmbroot/reco/L1/CbmL1.h:
        > add a L1Paramters class field (currently ptr to address in the heap) to CbmL1
        > add getter for the L1Parameters class field to CbmL1
      - cbmroot/reco/L1/CbmL1.cxx:
        > add transfer of the L1Parameters data from CbmL1 to L1Algo
        > modifications according to the constants transfer to the L1Parameters class (example: fkMaxNthreads ==> L1Parameters::kMaxNthreads)
      - cbmroot/macro/run/run_reco.C:
        > add example of L1Algo runtime constants modification
    f90e27f6
    History
    COMMIT FROM 23.12.2021
    sergeizharko authored
      - cbmroot/reco/L1/L1Algo/L1BaseStationInfo.h:
        > a prototype of user-friendly interface to L1Station and other geometry inputs to L1Algo (experimental)
        > added setters and getters for L1Station data fields
        > added calculation of hidden L1Station properties
        > added Print() method
      - cbmroot/reco/L1/L1Algo/L1Parameters.h:
        > add new compile time constants: kMaxNFieldApproxCoefficients, kStationBits, kThreadBits, kTripletBits,
          kMaxNstations, kMaxNthreads, kMaxNtriplets
        > add new runtime "constants": fMaxDoubletsPerSinglet, fMaxTripletPerDoublets
        > add Print() method
      - cbmroot/reco/L1/L1Algo/L1Algo.h:
        > modifications according to the constants transfer to the L1Parameters class (example: fkMaxNthreads ==> L1Parameters::kMaxNthreads)
      - cbmroot/reco/L1/L1Algo/L1Algo.cxx:
        > add L1Parameters::Print() call from L1Algo::Init()
        > modifications according to the constants transfer to the L1Parameters class (example: fkMaxNthreads ==> L1Parameters::kMaxNthreads)
      - cbmroot/reco/L1/L1Algo/L1CATrackFinder.cxx:
        > modifications according to the constants transfer to the L1Parameters class (example: fkMaxNthreads ==> L1Parameters::kMaxNthreads)
      - cbmroot/reco/L1/L1Algo/L1TrackFitter.cxx:
        > modifications according to the constants transfer to the L1Parameters class (example: fkMaxNthreads ==> L1Parameters::kMaxNthreads)
      - cbmroot/reco/L1/L1Algo/L1Field.h:
        > magic constant '21' changed to L1Parameters::kMaxNFieldApproxCoefficients (compile time)
      - cmbroot/reco/L1/CbmL1.h:
        > add a L1Paramters class field (currently ptr to address in the heap) to CbmL1
        > add getter for the L1Parameters class field to CbmL1
      - cbmroot/reco/L1/CbmL1.cxx:
        > add transfer of the L1Parameters data from CbmL1 to L1Algo
        > modifications according to the constants transfer to the L1Parameters class (example: fkMaxNthreads ==> L1Parameters::kMaxNthreads)
      - cbmroot/macro/run/run_reco.C:
        > add example of L1Algo runtime constants modification
L1BaseStationInfo.h 13.16 KiB
/* Copyright (C) 2016-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
   SPDX-License-Identifier: GPL-3.0-only
   Authors: Sergey Gorbunov, Sergei Zharko [committer] */

/**************************************************************************************************************
 * @file L1BaseStationInfo.h
 * @bried A base class for a L1 station interface
 * @since 18.12.2021
 *
 * The class is implemented to connect concrete experimental setup (CBM or BMN in CbmL1 
 * or BmnL1) with general L1Tracking algorithm. Each derived class must contain general
 * algorithms sutable for the particular station type.
 * 
 ***********************************************************************************************************/

#ifndef L1BaseStationInfo_h
#define L1BaseStationInfo_h 1

// L1 core
#include "L1Parameters.h"
#include "L1Station.h"
#include "L1Def.h"

// C++ std
#include <string>
#include <bitset>
#include <iomanip>
//#include <cmath>

/// A base class which provides interface to L1Algo station geometry

class L1BaseStationInfo {
 private:
  enum { // Here we list all the fields, which must be initialized by user
    // Basic fields initialization
    // L1Station initialization
    kEtype,
    kEtimeInfo,
    kEz,
    kERmin, 
    kERmax, 
    kEmaterialInfoThick, 
    kEmaterialInfoRL,
    kEfieldSlice,
    kEstripsFrontPhi,
    kEstripsFrontSigma,
    kEstripsBackPhi,
    kEstripsBackSigma,
    // The last item is equal to the number of bits in fInitFlags
    kEND
  };
 public:
  L1BaseStationInfo() {
    std::cout << ">>>>>> L1BaseStationInfo: Constructor called\n"; // Temporary
  }
  virtual ~L1BaseStationInfo() {
    std::cout << ">>>>>> L1BaseStationInfo: Destructor called\n"; // Temporary
  }

  //-------------------------------------------------------------------------------------------------------//
  //    Basic methods                                                                                      //
  //-------------------------------------------------------------------------------------------------------//
  
  /// Returns the name of the station (TODO: connect official naming)
  std::string GetTypeName() const { return fTypeName; }
  /// Checks if all the necessary fields are initialized by user
  bool IsInitialized() const { return fInitFlags.size() == fInitFlags.count(); }
  /// Transfers all gathered data to L1Algo (TODO)
  void TransferL1Station() { 
    /**********/
  }
  void TransferData() { /*********/ }    

  //-------------------------------------------------------------------------------------------------------//
  //    Interface for L1Station object initialization                                                      //
  //-------------------------------------------------------------------------------------------------------//

  //
  //  Setters
  //
  /// Sets type of station 
  void SetStationType(int inType)  { fL1Station.type = inType;         fInitFlags[kEtype] = true;}
    // TODO: Temporary method, a type must be selected automatically in the derived classes
  void SetTimeInfo(int inTimeInfo) { fL1Station.timeInfo = inTimeInfo; fInitFlags[kEtimeInfo] = true;}
    // ???

  /// Sets nominal z position of the station
  void SetZ(double inZ)        { fL1Station.z = inZ;        fInitFlags[kEz] = true; }
  /// Sets min transverse size of the station
  void SetRmin(double inRmin)  { fL1Station.Rmin = inRmin;  fInitFlags[kERmin] = true; }
  /// Sets max transverse size of the station
  void SetRmax(double inRmax)  { fL1Station.Rmax = inRmax;  fInitFlags[kERmax] = true; }

  /// Sets station thickness and radiational length
  void SetMaterial(double inThickness, double inRL) {
#ifndef L1_NO_ASSERT // check for zero denominator
    L1_ASSERT(inRL, "Attempt of entering zero inRL (radiational length) value");
#endif 
    fL1Station.materialInfo.thick = inThickness;
    fL1Station.materialInfo.RL = inRL;
    fL1Station.materialInfo.RadThick = fL1Station.materialInfo.thick / fL1Station.materialInfo.RL;
    fL1Station.materialInfo.logRadThick = log(fL1Station.materialInfo.RadThick);
    fInitFlags[kEmaterialInfoThick] = true;
    fInitFlags[kEmaterialInfoRL] = true;
  }

  /// Sets arrays of the approximation coefficients for the field x, y and z-components, respectively
  void SetFieldSlice(const double* Cx, const double* Cy, const double* Cz) {
    for (int idx = 0; idx < L1Parameters::kMaxNFieldApproxCoefficients; ++idx) {
      fL1Station.fieldSlice.cx[idx] = Cx[idx];
      fL1Station.fieldSlice.cy[idx] = Cy[idx];
      fL1Station.fieldSlice.cz[idx] = Cz[idx];
      fInitFlags[kEfieldSlice] = true;
    }
  }

  /// Sets stereo angles and sigmas for front and back strips, automatically set frontInfo, backInfo, 
  /// XYInfo, xInfo and yInfo
  void SetFrontBackStripsGeometry(double f_phi, double f_sigma, double b_phi, double b_sigma) { 
    // TODO: may be is it better to define separate setters for these values and then calculate the 
    //       rest somewhere below?
    // TODO: move into .cxx file

    //----- Original code from L1Algo ---------------------------------------------------------------------//
    double c_f     = cos(f_phi);
    double s_f     = sin(f_phi);
    double c_b     = cos(b_phi);
    double s_b     = sin(b_phi);

    // NOTE: Here additional double variables are used to save the precission

    fL1Station.frontInfo.cos_phi = c_f;
    fL1Station.frontInfo.sin_phi = s_f;
    fL1Station.frontInfo.sigma2  = f_sigma * f_sigma;

    fL1Station.backInfo.cos_phi = c_b;
    fL1Station.backInfo.sin_phi = s_b;
    fL1Station.backInfo.sigma2  = b_sigma * b_sigma;
  
    //if (fabs(b_phi - f_phi) < .1) {
    //  double th  = b_phi - f_phi;
    //  double det = cos(th);
    //  det *= det;
    //  fL1Station.XYInfo.C00 = (s_b * s_b * f_sigma * f_sigma + s_f * s_f * b_sigma * b_sigma) / det;
    //  fL1Station.XYInfo.C10 = -(s_b * c_b * f_sigma * f_sigma + s_f * c_f * b_sigma * b_sigma) / det;
    //  fL1Station.XYInfo.C11 = (c_b * c_b * f_sigma * f_sigma + c_f * c_f * b_sigma * b_sigma) / det;
    //} else {
    //  double det = c_f * s_b - s_f * c_b;
    //  det *= det;
    //  fL1Station.XYInfo.C00 = (s_b * s_b * f_sigma * f_sigma + s_f * s_f * b_sigma * b_sigma) / det;
    //  fL1Station.XYInfo.C10 = -(s_b * c_b * f_sigma * f_sigma + s_f * c_f * b_sigma * b_sigma) / det;
    //  fL1Station.XYInfo.C11 = (c_b * c_b * f_sigma * f_sigma + c_f * c_f * b_sigma * b_sigma) / det;
    //}

    double det = (fabs(b_phi - f_phi) < 0.1) ? cos(b_phi - f_phi) : (c_f * s_b - s_f * c_b);
    det *= det;
    fL1Station.XYInfo.C00 = (s_b * s_b * f_sigma * f_sigma + s_f * s_f * b_sigma * b_sigma) / det;
    fL1Station.XYInfo.C10 = -(s_b * c_b * f_sigma * f_sigma + s_f * c_f * b_sigma * b_sigma) / det;
    fL1Station.XYInfo.C11 = (c_b * c_b * f_sigma * f_sigma + c_f * c_f * b_sigma * b_sigma) / det;

    fL1Station.xInfo.cos_phi = -s_f / (c_f * s_b - c_b * s_f);
    fL1Station.xInfo.sin_phi = s_b / (c_f * s_b - c_b * s_f);
    fL1Station.xInfo.sigma2  = fL1Station.XYInfo.C00;

    fL1Station.yInfo.cos_phi = c_b / (c_b * s_f - c_f * s_b);
    fL1Station.yInfo.sin_phi = -c_f / (c_b * s_f - c_f * s_b);
    fL1Station.yInfo.sigma2  = fL1Station.XYInfo.C11;
    //-----------------------------------------------------------------------------------------------------//
 
    fInitFlags[kEstripsFrontPhi]   = true;
    fInitFlags[kEstripsFrontSigma] = true;
    fInitFlags[kEstripsBackPhi]    = true;
    fInitFlags[kEstripsBackSigma]  = true;
  }

  //
  // Getters
  //

  /// Gets nominal z position of the station
  fvec GetZ()                    const { return fL1Station.z; }
  /// Gets min transverse size of the station
  fvec GetRmin()                 const { return fL1Station.Rmin; }
  /// Gets max transverse size of the station
  fvec GetRmax()                 const { return fL1Station.Rmax; }

  /// Gets material thickness
  fvec GetMaterialThick()        const { return fL1Station.materialInfo.thick; }
    // TODO: investigate if thick, RL and RadThick are useful, may be we should have only 
    //       GetMateralLogRadThick?
  /// Gets the radiation length of the station material
  fvec GetMaterialRL()           const { return fL1Station.materialInfo.RL; }             // TODO: -//-
  /// Gets the relative material thickness in units of the radiational length
  fvec GetMaterialRadThick()     const { return fL1Station.materialInfo.RadThick; }       // TODO: Rename?
  /// Gets log of the relative material thickness in units of the radiational length
  fvec GetMaterialLogRadThick()  const { return fL1Station.materialInfo.logRadThick; }

  /// Gets a coefficient with idx for the field x-component approximation
  fvec GetFieldSliceCx(int idx)  const { return fL1Station.fieldSlice.cx[idx]; }
  /// Gets a coefficient with idx for the field y-component approximation
  fvec GetFieldSliceCy(int idx)  const { return fL1Station.fieldSlice.cy[idx]; }
  /// Gets a coefficient with idx for the field z-component approximation
  fvec GetFieldSliceCz(int idx)  const { return fL1Station.fieldSlice.cz[idx]; }

  /// Gets array of the coefficients for the field x-component approximation
  const fvec * GetFieldSliceCx() const { return fL1Station.fieldSlice.cx; }
  /// Gets array of the coefficients for the field y-component approximation
  const fvec * GetFieldSliceCy() const { return fL1Station.fieldSlice.cy; }
  /// Gets array of the coefficients for the field z-component approximation
  const fvec * GetFieldSliceCz() const { return fL1Station.fieldSlice.cz; }


  //-------------------------------------------------------------------------------------------------------//
  //    Other methods                                                                                      //
  //-------------------------------------------------------------------------------------------------------//

  /// Prints registered fields (TODO: tmp, may be one needs to wrap it into debug directives)
  void Print() { 
    LOG(INFO) << "== L1Algo: station info ===========================================================";
    LOG(INFO) << "";
    LOG(INFO) << "  L1Station fields:";
    LOG(INFO) << "    z position:              " << fL1Station.z[0] ;
    LOG(INFO) << "    Rmin:                    " << fL1Station.Rmin[0] ;
    LOG(INFO) << "    Rmax:                    " << fL1Station.Rmax[0] ;
    LOG(INFO) << "    Thickness (X):           " << fL1Station.materialInfo.thick[0] ;
    LOG(INFO) << "    Radiational length (X0): " << fL1Station.materialInfo.RL[0] ;
    LOG(INFO) << "    X / X0:                  " << fL1Station.materialInfo.RadThick[0] ;
    LOG(INFO) << "    log(X / X0):             " << fL1Station.materialInfo.logRadThick[0] ;
    LOG(INFO) << "    Field approximation coefficients:";
    LOG(INFO) << "      idx         CX         CY         CZ";
    for (int idx = 0; idx < L1Parameters::kMaxNFieldApproxCoefficients; ++idx) {
      LOG(INFO) << std::setw(9)  << std::setfill(' ') << idx << ' '
                << std::setw(10) << std::setfill(' ') << fL1Station.fieldSlice.cx[idx][0] << ' '
                << std::setw(10) << std::setfill(' ') << fL1Station.fieldSlice.cy[idx][0] << ' '
                << std::setw(10) << std::setfill(' ') << fL1Station.fieldSlice.cz[idx][0];
    }
    LOG(INFO) << "    Strips geometry:";
    LOG(INFO) << "      Front:";
    LOG(INFO) << "        cos(phi):            " << fL1Station.frontInfo.cos_phi[0];
    LOG(INFO) << "        sin(phi):            " << fL1Station.frontInfo.sin_phi[0];
    LOG(INFO) << "        sigma2:              " << fL1Station.frontInfo.sigma2[0];
    LOG(INFO) << "      Back:";
    LOG(INFO) << "        cos(phi):            " << fL1Station.backInfo.cos_phi[0];
    LOG(INFO) << "        sin(phi):            " << fL1Station.backInfo.sin_phi[0];
    LOG(INFO) << "        sigma2:              " << fL1Station.backInfo.sigma2[0];
    LOG(INFO) << "      XY cov matrix:";
    LOG(INFO) << "        C00:                 " << fL1Station.XYInfo.C00[0];
    LOG(INFO) << "        C10:                 " << fL1Station.XYInfo.C10[0];
    LOG(INFO) << "        C11:                 " << fL1Station.XYInfo.C11[0];
    LOG(INFO) << "      X layer:";
    LOG(INFO) << "        cos(phi):            " << fL1Station.xInfo.cos_phi[0];
    LOG(INFO) << "        sin(phi):            " << fL1Station.xInfo.sin_phi[0];
    LOG(INFO) << "        sigma2:              " << fL1Station.xInfo.sigma2[0];
    LOG(INFO) << "      Y layer:";
    LOG(INFO) << "        cos(phi):            " << fL1Station.yInfo.cos_phi[0];
    LOG(INFO) << "        sin(phi):            " << fL1Station.yInfo.sin_phi[0];
    LOG(INFO) << "        sigma2:              " << fL1Station.yInfo.sigma2[0];
    LOG(INFO) << "";
    LOG(INFO) << "===================================================================================";
  }
 private:
  /// Flags set. A particular flag is up if the corresponding setter was called (experimental)
  std::bitset<L1BaseStationInfo::kEND> fInitFlags;
  std::string                          fTypeName {"BASE"};
  L1Station                            fL1Station {}; 
    // TODO (!!!!) MUST THINK ABOUT THIS OBJECT LIFE TIME: will it be better to copy
    //             or to move it to the core? If the second, what should we do with 
    //             getters? Do we need to lock them, when the fL1Station object will 
    //             be transfered?

 

};



#endif // L1BaseStationInfo_h