Address

AddressBox

AddressMask

Detector

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
/*
 * =====================================================================================
 *
 *       Filename:  CSCDQM_Detector.h
 *
 *    Description:  CSC detector functions.
 *
 *        Version:  1.0
 *        Created:  05/19/2008 10:52:21 AM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Valdas Rapsevicius (VR), Valdas.Rapsevicius@cern.ch
 *        Company:  CERN, CH
 *
 * =====================================================================================
 */

#ifndef CSCDQM_Detector_H
#define CSCDQM_Detector_H

#include <cmath>
#include <cfloat>
#include <map>
#include <vector>
#include <iostream>
#include <sstream>
#include <iomanip>

#ifdef CSC_RENDER_PLUGIN
#include "CSCDQM_Utility.h"
#else
#include "CSCDQM_Utility.h"
#endif

namespace cscdqm {

  /**
 * Number of Detector Components.
 */

#define N_SIDES 2
#define N_STATIONS 4
#define N_RINGS 3
#define N_CHAMBERS 36
#define N_LAYERS 6
#define N_CFEBS 5
#define N_HVS 5

/** Size of the address (number of components) */
#define ADDR_SIZE 7

/** Number of addressing elements in detector */
#define N_ELEMENTS 9540
  //(7740 + 1800)

  /**
 * Partition function shortcuts
 */

#define PARTITION_INDEX(x, y) (x * partitions_y + y)
#define PARTITION_STEP_X (5.0 / partitions_x)
#define PARTITION_STEP_Y ((2.0 * 3.14159) / partitions_y)

  /**
 * @brief  Mask of the address which is used to switch on and off appropriate Address fields.
 */
  struct AddressMask {
    bool side;
    bool station;
    bool ring;
    bool chamber;
    bool layer;
    bool cfeb;
    bool hv;
  };

  /**
 * @brief  Structure to store detector addresses of any granularity: from
 * whole detector to the single HV element.
 */
  struct Address {
    unsigned int side;
    unsigned int station;
    unsigned int ring;
    unsigned int chamber;
    unsigned int layer;
    unsigned int cfeb;
    unsigned int hv;

    AddressMask mask;

    const bool operator==(const Address& a) const {
      if (mask.side == a.mask.side && mask.side == true && side != a.side)
        return false;
      if (mask.station == a.mask.station && mask.station == true && station != a.station)
        return false;
      if (mask.ring == a.mask.ring && mask.ring == true && ring != a.ring)
        return false;
      if (mask.chamber == a.mask.chamber && mask.chamber == true && chamber != a.chamber)
        return false;
      if (mask.layer == a.mask.layer && mask.layer == true && layer != a.layer)
        return false;
      if (mask.cfeb == a.mask.cfeb && mask.cfeb == true && cfeb != a.cfeb)
        return false;
      if (mask.hv == a.mask.hv && mask.hv == true && hv != a.hv)
        return false;
      return true;
    };

    friend std::ostream& operator<<(std::ostream& out, const Address& adr) {
      out << adr.name();
      return out;
    }

    /**
   * @brief  Get the full name of the address prefixed with CSC_. It is being used by summaryReportContent variables
   * @return Address name as string
   */
    const std::string name() const {
      std::ostringstream oss;
      oss << "CSC";
      if (mask.side) {
        oss << "_Side" << (side == 1 ? "Plus" : "Minus");
        if (mask.station) {
          oss << "_Station" << std::setfill('0') << std::setw(2) << station;
          if (mask.ring) {
            oss << "_Ring" << std::setfill('0') << std::setw(2) << ring;
            if (mask.chamber) {
              oss << "_Chamber" << std::setfill('0') << std::setw(2) << chamber;
              if (mask.layer) {
                oss << "_Layer" << std::setfill('0') << std::setw(2) << layer;
                if (mask.cfeb) {
                  oss << "_CFEB" << std::setfill('0') << std::setw(2) << cfeb;
                  if (mask.hv) {
                    oss << "_HV" << std::setfill('0') << std::setw(2) << hv;
                  }
                }
              }
            }
          }
        }
      }
      return oss.str();
    }
  };

  /**
 * @brief  Area covered by Address in eta/phy space
 */
  struct AddressBox {
    Address adr;
    float xmin;
    float xmax;
    float ymin;
    float ymax;
  };

  /** Map of partitions and partition covering adresses indexes type */
  typedef std::map<const unsigned int, std::vector<unsigned int> > PartitionMap;

  /** Iterator type of PartitionMap */
  typedef PartitionMap::iterator PartitionMapIterator;

  /**
 * @class Detector
 * @brief Detector geometry and addressing related imformation and routines
 */
  class Detector {
  public:
    Detector(const unsigned int p_partitions_x = 0, const unsigned int p_partitions_y = 0);

    const bool NextAddress(unsigned int& i, const Address*& adr, const Address& mask) const;
    const bool NextAddressBox(unsigned int& i, const AddressBox*& box, const Address& mask) const;
    //const bool NextAddressBoxByPartition(unsigned int& i, unsigned int& px, unsigned int& py, const AddressBox*& box, const Address& mask, const float xmin, const float xmax, const float ymin, const float ymax);
    const bool NextAddressBoxByPartition(unsigned int& i,
                                         const unsigned int px,
                                         const unsigned int py,
                                         AddressBox*& box);

    const float Area(const unsigned int station) const;
    const float Area(const Address& adr) const;

    void PrintAddress(const Address& adr) const;
    const bool AddressFromString(const std::string& str_address, Address& adr) const;

    const unsigned int NumberOfRings(const unsigned int station) const;
    const unsigned int NumberOfChambers(const unsigned int station, const unsigned int ring) const;
    const unsigned int NumberOfChamberCFEBs(const unsigned int station, const unsigned int ring) const;
    const unsigned int NumberOfChamberHVs(const unsigned int station, const unsigned int ring) const;
    unsigned int GlobalChamberIndex(unsigned int side,
                                    unsigned int station,
                                    unsigned int ring,
                                    unsigned int chamber) const;

  private:
    const float Eta(const float r, const float z) const;
    const float EtaToX(const float eta) const;
    const float PhiToY(const float phi) const;
    const float Z(const int station, const int ring) const;
    const float RMinHV(const int station, const int ring, const int n_hv) const;
    const float RMaxHV(const int station, const int ring, const int n_hv) const;
    const float PhiMinCFEB(const int station, const int ring, const int chamber, const int cfeb) const;
    const float PhiMaxCFEB(const int station, const int ring, const int chamber, const int cfeb) const;

    /** Address boxes in epa/phi space */
    AddressBox boxes[N_ELEMENTS];

    /** Station areas precalculated */
    float station_area[N_STATIONS];

    /** Number of partitions in X axis */
    unsigned int partitions_x;

    /** Number of partitions in Y axis */
    unsigned int partitions_y;

    /** Map of partitions and list of it covering addresses indexes */
    PartitionMap partitions;
  };

}  // namespace cscdqm

#endif