Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:06:55

0001 /*
0002  * =====================================================================================
0003  *
0004  *       Filename:  Detector.cc
0005  *
0006  *    Description:  Class Detector implementation
0007  *
0008  *        Version:  1.0
0009  *        Created:  05/19/2008 10:59:34 AM
0010  *       Revision:  none
0011  *       Compiler:  gcc
0012  *
0013  *         Author:  Valdas Rapsevicius (VR), Valdas.Rapsevicius@cern.ch
0014  *        Company:  CERN, CH
0015  *
0016  * =====================================================================================
0017  */
0018 
0019 #ifdef CSC_RENDER_PLUGIN
0020 #include "CSCDQM_Detector.h"
0021 #else
0022 #include "CSCDQM_Detector.h"
0023 #endif
0024 
0025 namespace cscdqm {
0026 
0027   /**
0028    * @brief  Constructor
0029    * @param  p_partition_x Number of efficiency partitions on X axis
0030    * @param  p_partition_y Number of efficiency partitions on Y axis
0031    * @return 
0032    */
0033   Detector::Detector(const unsigned int p_partitions_x, const unsigned int p_partitions_y) {
0034     partitions_x = p_partitions_x;
0035     partitions_y = p_partitions_y;
0036 
0037     unsigned int i = 0;
0038     Address adr;
0039 
0040     adr.mask.layer = false;
0041     adr.mask.side = adr.mask.station = adr.mask.ring = adr.mask.chamber = adr.mask.cfeb = adr.mask.hv = true;
0042 
0043     /**  Creating real eta/phi boxes for available addresses */
0044     for (adr.side = 1; adr.side <= N_SIDES; adr.side++) {
0045       float sign = +1.0;
0046       if (adr.side == 2)
0047         sign = -1.0;
0048       for (adr.station = 1; adr.station <= N_STATIONS; adr.station++) {
0049         for (adr.ring = 1; adr.ring <= NumberOfRings(adr.station); adr.ring++) {
0050           for (adr.chamber = 1; adr.chamber <= NumberOfChambers(adr.station, adr.ring); adr.chamber++) {
0051             for (adr.cfeb = 1; adr.cfeb <= NumberOfChamberCFEBs(adr.station, adr.ring); adr.cfeb++) {
0052               for (adr.hv = 1; adr.hv <= NumberOfChamberHVs(adr.station, adr.ring); adr.hv++) {
0053                 float z = Z(adr.station, adr.ring);
0054                 float r_min = RMinHV(adr.station, adr.ring, adr.hv);
0055                 float r_max = RMaxHV(adr.station, adr.ring, adr.hv);
0056                 float eta_min = sign * Eta(r_min, z);
0057                 float eta_max = sign * Eta(r_max, z);
0058                 float x_min = EtaToX(eta_min);
0059                 float x_max = EtaToX(eta_max);
0060                 float phi_min = 0;
0061                 float phi_max = 0;
0062 
0063                 if (adr.station == 1 && adr.ring == 1 && adr.hv == 1) {
0064                   phi_min = PhiMinCFEB(adr.station, adr.ring, adr.chamber, 1);
0065                   phi_max = PhiMaxCFEB(adr.station, adr.ring, adr.chamber, NumberOfChamberCFEBs(adr.station, adr.ring));
0066                 } else {
0067                   phi_min = PhiMinCFEB(adr.station, adr.ring, adr.chamber, adr.cfeb);
0068                   phi_max = PhiMaxCFEB(adr.station, adr.ring, adr.chamber, adr.cfeb);
0069                 }
0070 
0071                 float y_min = PhiToY(phi_min);
0072                 float y_max = PhiToY(phi_max);
0073 
0074                 boxes[i].adr = adr;
0075 
0076                 float xboxmin = (x_min < x_max ? x_min : x_max);
0077                 float xboxmax = (x_max > x_min ? x_max : x_min);
0078                 float yboxmin = (y_min < y_max ? y_min : y_max);
0079                 float yboxmax = (y_max > y_min ? y_max : y_min);
0080 
0081                 boxes[i].xmin = xboxmin;
0082                 boxes[i].xmax = xboxmax;
0083                 boxes[i].ymin = yboxmin;
0084                 boxes[i].ymax = yboxmax;
0085 
0086                 /** Address box calculated successfully. Now lets cache its
0087                  * partition elements for performace. */
0088 
0089                 unsigned int x1 = int(floor(xboxmin / PARTITION_STEP_X)) + int(partitions_x / 2);
0090                 unsigned int x2 = int(ceil(xboxmax / PARTITION_STEP_X)) + int(partitions_x / 2);
0091                 unsigned int y1 = int(floor(yboxmin / PARTITION_STEP_Y));
0092                 unsigned int y2 = int(ceil(yboxmax / PARTITION_STEP_Y));
0093 
0094                 for (unsigned int x = x1; x < x2; x++) {
0095                   for (unsigned int y = y1; y < y2; y++) {
0096                     unsigned int index = PARTITION_INDEX(x, y);
0097                     PartitionMapIterator iter = partitions.find(index);
0098                     if (iter == partitions.end()) {
0099                       std::vector<unsigned int> v;
0100                       partitions.insert(std::make_pair(index, v));
0101                     }
0102                     partitions[index].push_back(i);
0103                   }
0104                 }
0105 
0106                 i++;
0107               }
0108             }
0109           }
0110         }
0111       }
0112     }
0113 
0114     /**  Cached the most frequently used areas */
0115     adr.mask.side = adr.mask.ring = adr.mask.chamber = adr.mask.layer = adr.mask.cfeb = adr.mask.hv = false;
0116     adr.mask.station = true;
0117     adr.station = 1;
0118     station_area[0] = Area(adr);
0119     adr.station = 2;
0120     station_area[1] = Area(adr);
0121     adr.station = 3;
0122     station_area[2] = Area(adr);
0123     adr.station = 4;
0124     station_area[3] = Area(adr);
0125   }
0126 
0127   /**
0128    * @brief  Calculate station area in eta/phi space
0129    * @param  station Station number
0130    * @return Area that is being covered by station
0131    */
0132   const float Detector::Area(const unsigned int station) const {
0133     if (station > 0 && station <= N_STATIONS) {
0134       return station_area[station - 1];
0135     }
0136     return 0;
0137   }
0138 
0139   /**
0140    * @brief  Return global chamber index on his geometric location
0141    * @param  side Side (1,2)
0142    * @param  station Station
0143    * @param  ring Ring\
0144    * @param  chamber Chamber position
0145    * @return Global chamber index starting 1. If chamber is not existing - returns 0
0146    */
0147   unsigned int Detector::GlobalChamberIndex(unsigned int side,
0148                                             unsigned int station,
0149                                             unsigned int ring,
0150                                             unsigned int chamber) const {
0151     Address adr, iadr;
0152     adr.mask.side = adr.mask.station = adr.mask.ring = adr.mask.chamber = true;
0153     adr.mask.layer = adr.mask.cfeb = adr.mask.hv = false;
0154     adr.layer = adr.cfeb = adr.hv = 0;
0155     adr.side = side;
0156     adr.station = station;
0157     adr.ring = ring;
0158     adr.chamber = chamber;
0159     iadr = adr;
0160 
0161     unsigned int i = 1;
0162     for (iadr.side = 1; iadr.side <= N_SIDES; iadr.side++) {
0163       for (iadr.station = 1; iadr.station <= N_STATIONS; iadr.station++) {
0164         for (iadr.ring = 1; iadr.ring <= NumberOfRings(iadr.station); iadr.ring++) {
0165           for (iadr.chamber = 1; iadr.chamber <= NumberOfChambers(iadr.station, iadr.ring); iadr.chamber++) {
0166             if (iadr == adr) {
0167               return i;
0168             }
0169             i += 1;
0170           }
0171         }
0172       }
0173     }
0174     return 0;
0175   }
0176 
0177   /**
0178    * @brief  Calculate address area in eta/phi space
0179    * @param  adr Address
0180    * @return Area that is being covered by address
0181    */
0182   const float Detector::Area(const Address& adr) const {
0183     float a = 0;
0184     for (unsigned int i = 0; i < N_ELEMENTS; i++) {
0185       if (boxes[i].adr == adr) {
0186         a += fabs((boxes[i].xmax - boxes[i].xmin) * (boxes[i].ymax - boxes[i].ymin));
0187       }
0188     }
0189     return a;
0190   }
0191 
0192   /**
0193    * @brief  Returns the number of rings for the given station
0194    * @param  station Station number (1, 2, 3, 4)
0195    * @return number of rings for the given station
0196    */
0197   const unsigned int Detector::NumberOfRings(const unsigned int station) const {
0198     if (station == 1)
0199       return 3;
0200     if (station == 2)
0201       return 2;
0202     if (station == 3)
0203       return 2;
0204     if (station == 4)
0205       return 2;
0206     return 0;
0207   }
0208 
0209   /**
0210    * @brief  Returns the number of chambers for the given station and ring
0211    * @param  station Station number (1...4)
0212    * @param  ring Ring number (1...3)
0213    * @return number of chambers
0214    */
0215   const unsigned int Detector::NumberOfChambers(const unsigned int station, const unsigned int ring) const {
0216     if (station == 1 && ring == 1)
0217       return 36;
0218     if (station == 1 && ring == 2)
0219       return 36;
0220     if (station == 1 && ring == 3)
0221       return 36;
0222     if (station == 2 && ring == 1)
0223       return 18;
0224     if (station == 2 && ring == 2)
0225       return 36;
0226     if (station == 3 && ring == 1)
0227       return 18;
0228     if (station == 3 && ring == 2)
0229       return 36;
0230     if (station == 4 && ring == 1)
0231       return 18;
0232     if (station == 4 && ring == 2)
0233       return 36;
0234     return 0;
0235   }
0236 
0237   /**
0238    * @brief  Returns the number of CFEBs per Chamber on given Station/Ring
0239    * @param  station Station number (1...4)
0240    * @param  ring Ring number (1...3)
0241    * @return Number of CFEBs per Chamber
0242    */
0243   const unsigned int Detector::NumberOfChamberCFEBs(const unsigned int station, const unsigned int ring) const {
0244     if (station == 1 && ring == 1)
0245       return 4;
0246     if (station == 1 && ring == 2)
0247       return 5;
0248     if (station == 1 && ring == 3)
0249       return 4;
0250     if (station == 2 && ring == 1)
0251       return 5;
0252     if (station == 2 && ring == 2)
0253       return 5;
0254     if (station == 3 && ring == 1)
0255       return 5;
0256     if (station == 3 && ring == 2)
0257       return 5;
0258     if (station == 4 && ring == 1)
0259       return 5;
0260     if (station == 4 && ring == 2)
0261       return 5;
0262     return 0;
0263   }
0264 
0265   /**
0266    * @brief   Returns the number of HVs per Chamber on given Station/Ring
0267    * @param  station Station number (1...4)
0268    * @param  ring Ring number (1...3)
0269    * @return Number of HVs per Chamber
0270    */
0271   const unsigned int Detector::NumberOfChamberHVs(const unsigned int station, const unsigned int ring) const {
0272     if (station == 1 && ring == 1)
0273       return 2;
0274     if (station == 1 && ring == 2)
0275       return 3;
0276     if (station == 1 && ring == 3)
0277       return 3;
0278     if (station == 2 && ring == 1)
0279       return 3;
0280     if (station == 2 && ring == 2)
0281       return 5;
0282     if (station == 3 && ring == 1)
0283       return 3;
0284     if (station == 3 && ring == 2)
0285       return 5;
0286     if (station == 4 && ring == 1)
0287       return 3;
0288     if (station == 4 && ring == 2)
0289       return 5;
0290     return 0;
0291   }
0292 
0293   /**
0294    * @brief  Prints address for debugging
0295    * @param  adr Address to print
0296    * @return 
0297    */
0298   void Detector::PrintAddress(const Address& adr) const {
0299     std::cout << "Side (" << std::boolalpha << adr.mask.side << ")";
0300     if (adr.mask.side)
0301       std::cout << " = " << adr.side;
0302 
0303     std::cout << ", Station (" << std::boolalpha << adr.mask.station << ")";
0304     if (adr.mask.station)
0305       std::cout << " = " << adr.station;
0306 
0307     std::cout << ", Ring (" << std::boolalpha << adr.mask.ring << ")";
0308     if (adr.mask.ring)
0309       std::cout << " = " << adr.ring;
0310 
0311     std::cout << ", Chamber (" << std::boolalpha << adr.mask.chamber << ")";
0312     if (adr.mask.chamber)
0313       std::cout << " = " << adr.chamber;
0314 
0315     std::cout << ", Layer (" << std::boolalpha << adr.mask.layer << ")";
0316     if (adr.mask.layer)
0317       std::cout << " = " << adr.layer;
0318 
0319     std::cout << ", CFEB (" << std::boolalpha << adr.mask.cfeb << ")";
0320     if (adr.mask.cfeb)
0321       std::cout << " = " << adr.cfeb;
0322 
0323     std::cout << ", HV (" << std::boolalpha << adr.mask.hv << ")";
0324     if (adr.mask.hv)
0325       std::cout << " = " << adr.hv;
0326 
0327     std::cout << std::endl;
0328   }
0329 
0330   /**
0331    * @brief  Address iterator by mask
0332    * @param  i Iterator
0333    * @param  adr Address to return
0334    * @param  mask for addresses
0335    * @return true if address was found and filled in, false - otherwise 
0336    */
0337   const bool Detector::NextAddress(unsigned int& i, const Address*& adr, const Address& mask) const {
0338     for (; i < N_ELEMENTS; i++) {
0339       if (boxes[i].adr == mask) {
0340         adr = &boxes[i].adr;
0341         i++;
0342         return true;
0343       }
0344     }
0345     return false;
0346   }
0347 
0348   /**
0349    * @brief  Address box iterator by mask
0350    * @param  i Iterator
0351    * @param  adr AddressBox to return
0352    * @param  mask for addresses
0353    * @return true if address box was found and filled in, false - otherwise 
0354    */
0355   const bool Detector::NextAddressBox(unsigned int& i, const AddressBox*& box, const Address& mask) const {
0356     for (; i < N_ELEMENTS; i++) {
0357       if (boxes[i].adr == mask) {
0358         box = &boxes[i];
0359         i++;
0360         return true;
0361       }
0362     }
0363     return false;
0364   }
0365 
0366   /**
0367    * @brief  Address box iterator by partition
0368    * @param  i Iterator
0369    * @param  px Partition x index
0370    * @param  py Partition y index
0371    * @param  box AddressBox to return
0372    * @return true if address box was found and filled in, false - otherwise 
0373    */
0374   const bool Detector::NextAddressBoxByPartition(unsigned int& i,
0375                                                  const unsigned int px,
0376                                                  const unsigned int py,
0377                                                  AddressBox*& box) {
0378     unsigned int index = PARTITION_INDEX(px, py);
0379 
0380     PartitionMapIterator iter = partitions.find(index);
0381     if (iter != partitions.end()) {
0382       if (i < partitions[index].size()) {
0383         box = &boxes[partitions[index].at(i)];
0384         i++;
0385         return true;
0386       }
0387     }
0388     return false;
0389   }
0390 
0391   const float Detector::Eta(const float r, const float z) const {
0392     if (r > 0.0 || z > 0.0) {
0393       float sin_theta = r / sqrt(r * r + z * z);
0394       float cos_theta = z / sqrt(r * r + z * z);
0395       return -log(sin_theta / (cos_theta + 1));
0396     }
0397     if (r == 0.0)
0398       return FLT_MAX;
0399     return 0.0;
0400   }
0401 
0402   /**
0403    * @brief   Transform eta coordinate to local canvas coordinate
0404    * @param  eta Eta coordinate
0405    * @return local canvas coordinate
0406    */
0407   const float Detector::EtaToX(const float eta) const {
0408     float x_min = -2.5;
0409     float x_max = 2.5;
0410     float eta_min = -2.5;
0411     float eta_max = 2.5;
0412     float a = (x_max - x_min) / (eta_max - eta_min);
0413     float b = (eta_max * x_min - eta_min * x_max) / (eta_max - eta_min);
0414     return a * eta + b;
0415   }
0416 
0417   /**
0418    * @brief   Transform phi coordinate to local canvas coordinate
0419    * @param  phi Phi coordinate
0420    * @return local canvas coordinate
0421    */
0422   const float Detector::PhiToY(const float phi) const {
0423     float y_min = 0.0;
0424     float y_max = 2.0 * 3.14159;
0425     float phi_min = 0.0;
0426     float phi_max = 2.0 * 3.14159;
0427     float a = (y_max - y_min) / (phi_max - phi_min);
0428     float b = (phi_max * y_min - phi_min * y_max) / (phi_max - phi_min);
0429     return a * phi + b;
0430   }
0431 
0432   /**
0433    * @brief  Get Z parameter (used in address eta/phi calculation)
0434    * @param  station Station Id
0435    * @param  ring Ring Id
0436    * @return Z value
0437    */
0438   const float Detector::Z(const int station, const int ring) const {
0439     float z_csc = 0;
0440 
0441     if (station == 1 && ring == 1)
0442       z_csc = (5834.5 + 6101.5) / 2.0;
0443     if (station == 1 && ring == 2)
0444       z_csc = (6790.0 + 7064.3) / 2.0;
0445     if (station == 1 && ring == 3)
0446       z_csc = 6888.0;
0447     if (station == 2)
0448       z_csc = (8098.0 + 8346.0) / 2.0;
0449     if (station == 3)
0450       z_csc = (9414.8 + 9166.8) / 2.0;
0451     if (station == 4)
0452       z_csc = 10630.0;  // has to be corrected
0453 
0454     return z_csc;
0455   }
0456 
0457   /**
0458    * @brief  Get R min parameter (used in address eta/phi calculation)
0459    * @param  station Station Id
0460    * @param  ring Ring Id
0461    * @param  n_hv HV number
0462    * @return R min value
0463    */
0464   const float Detector::RMinHV(const int station, const int ring, const int n_hv) const {
0465     float r_min_hv = 0;
0466 
0467     if (station == 1 && ring == 1) {
0468       if (n_hv == 1)
0469         r_min_hv = 1060.0;
0470       if (n_hv == 2)
0471         r_min_hv = 1500.0;
0472     }
0473 
0474     if (station == 1 && ring == 2) {
0475       if (n_hv == 1)
0476         r_min_hv = 2815.0;
0477       if (n_hv == 2)
0478         r_min_hv = 3368.2;
0479       if (n_hv == 3)
0480         r_min_hv = 4025.7;
0481     }
0482 
0483     if (station == 1 && ring == 3) {
0484       if (n_hv == 1)
0485         r_min_hv = 5120.0;
0486       if (n_hv == 2)
0487         r_min_hv = 5724.1;
0488       if (n_hv == 3)
0489         r_min_hv = 6230.2;
0490     }
0491 
0492     if (station == 2 && ring == 1) {
0493       if (n_hv == 1)
0494         r_min_hv = 1469.2;
0495       if (n_hv == 2)
0496         r_min_hv = 2152.3;
0497       if (n_hv == 3)
0498         r_min_hv = 2763.7;
0499     }
0500 
0501     if (station == 3 && ring == 1) {
0502       if (n_hv == 1)
0503         r_min_hv = 1668.9;
0504       if (n_hv == 2)
0505         r_min_hv = 2164.9;
0506       if (n_hv == 3)
0507         r_min_hv = 2763.8;
0508     }
0509 
0510     if (station == 4 && ring == 1) {
0511       if (n_hv == 1)
0512         r_min_hv = 1876.1;
0513       if (n_hv == 2)
0514         r_min_hv = 2365.9;
0515       if (n_hv == 3)
0516         r_min_hv = 2865.0;
0517     }
0518 
0519     if ((station == 2 || station == 3 || station == 4) && ring == 2) {
0520       if (n_hv == 1)
0521         r_min_hv = 3640.2;
0522       if (n_hv == 2)
0523         r_min_hv = 4446.3;
0524       if (n_hv == 3)
0525         r_min_hv = 5053.2;
0526       if (n_hv == 4)
0527         r_min_hv = 5660.1;
0528       if (n_hv == 5)
0529         r_min_hv = 6267.0;
0530     }
0531 
0532     return r_min_hv;
0533   }
0534 
0535   /**
0536    * @brief  Get R max parameter (used in address eta/phi calculation)
0537    * @param  station Station Id
0538    * @param  ring Ring Id
0539    * @param  n_hv HV number
0540    * @return R max value
0541    */
0542   const float Detector::RMaxHV(const int station, const int ring, const int n_hv) const {
0543     float r_max_hv = 0;
0544 
0545     if (station == 1 && ring == 1) {
0546       if (n_hv == 1)
0547         r_max_hv = 1500.0;
0548       if (n_hv == 2)
0549         r_max_hv = 2565.0;
0550     }
0551 
0552     if (station == 1 && ring == 2) {
0553       if (n_hv == 1)
0554         r_max_hv = 3368.2;
0555       if (n_hv == 2)
0556         r_max_hv = 4025.7;
0557       if (n_hv == 3)
0558         r_max_hv = 4559.9;
0559     }
0560 
0561     if (station == 1 && ring == 3) {
0562       if (n_hv == 1)
0563         r_max_hv = 5724.1;
0564       if (n_hv == 2)
0565         r_max_hv = 6230.2;
0566       if (n_hv == 3)
0567         r_max_hv = 6761.5;
0568     }
0569 
0570     if (station == 2 && ring == 1) {
0571       if (n_hv == 1)
0572         r_max_hv = 2152.3;
0573       if (n_hv == 2)
0574         r_max_hv = 2763.7;
0575       if (n_hv == 3)
0576         r_max_hv = 3365.8;
0577     }
0578 
0579     if (station == 3 && ring == 1) {
0580       if (n_hv == 1)
0581         r_max_hv = 2164.9;
0582       if (n_hv == 2)
0583         r_max_hv = 2763.8;
0584       if (n_hv == 3)
0585         r_max_hv = 3365.8;
0586     }
0587 
0588     if (station == 4 && ring == 1) {
0589       if (n_hv == 1)
0590         r_max_hv = 2365.9;
0591       if (n_hv == 2)
0592         r_max_hv = 2865.0;
0593       if (n_hv == 3)
0594         r_max_hv = 3356.3;
0595     }
0596 
0597     if ((station == 2 || station == 3 || station == 4) && ring == 2) {
0598       if (n_hv == 1)
0599         r_max_hv = 4446.3;
0600       if (n_hv == 2)
0601         r_max_hv = 5053.2;
0602       if (n_hv == 3)
0603         r_max_hv = 5660.1;
0604       if (n_hv == 4)
0605         r_max_hv = 6267.0;
0606       if (n_hv == 5)
0607         r_max_hv = 6870.8;
0608     }
0609 
0610     return r_max_hv;
0611   }
0612 
0613   /**
0614    * @brief  Get Min phi boundary for particular CFEB
0615    * @param  station Station number
0616    * @param  ring Ring number
0617    * @param  chamber Chamber number
0618    * @param  cfeb CFEB number
0619    * @return Min phi CFEB boundary
0620    */
0621   const float Detector::PhiMinCFEB(const int station, const int ring, const int chamber, const int cfeb) const {
0622     float phi_min_cfeb;
0623 
0624     int n_cfeb = NumberOfChamberCFEBs(station, ring);
0625     int n_chambers = NumberOfChambers(station, ring);
0626 
0627     phi_min_cfeb =
0628         0.0 + 2.0 * 3.14159 / ((float)(n_chambers)) * ((float)(chamber - 1) + (float)(cfeb - 1) / (float)(n_cfeb));
0629 
0630     return phi_min_cfeb;
0631   }
0632 
0633   /**
0634    * @brief  Get Max phi boundary for particular CFEB
0635    * @param  station Station number
0636    * @param  ring Ring number
0637    * @param  chamber Chamber number
0638    * @param  cfeb CFEB number
0639    * @return Max phi CFEB boundary
0640    */
0641   const float Detector::PhiMaxCFEB(const int station, const int ring, const int chamber, const int cfeb) const {
0642     float phi_max_cfeb;
0643 
0644     int n_cfeb = NumberOfChamberCFEBs(station, ring);
0645     int n_chambers = NumberOfChambers(station, ring);
0646 
0647     phi_max_cfeb = 0.0 + 2.0 * 3.14159 / (float)n_chambers * ((float)(chamber - 1) + (float)(cfeb) / (float)n_cfeb);
0648 
0649     return phi_max_cfeb;
0650   }
0651 
0652   /**
0653    * @brief  Construct address from string
0654    * @param  str_address Address in string
0655    * @param  adr Address to return
0656    * @return true if address was successfully created, false - otherwise
0657    */
0658   const bool Detector::AddressFromString(const std::string& str_address, Address& adr) const {
0659     std::vector<std::string> tokens;
0660     Utility::splitString(str_address, ",", tokens);
0661 
0662     if (tokens.size() != ADDR_SIZE)
0663       return false;
0664 
0665     for (unsigned int r = 0; r < ADDR_SIZE; r++) {
0666       std::string token = tokens.at(r);
0667       Utility::trimString(token);
0668       bool mask = false;
0669       unsigned int num = 0;
0670 
0671       if (token != "*") {
0672         if (stringToNumber<unsigned int>(num, token, std::dec)) {
0673           mask = true;
0674         } else {
0675           return false;
0676         }
0677       }
0678 
0679       switch (r) {
0680         case 0:
0681           adr.mask.side = mask;
0682           adr.side = num;
0683           break;
0684         case 1:
0685           adr.mask.station = mask;
0686           adr.station = num;
0687           break;
0688         case 2:
0689           adr.mask.ring = mask;
0690           adr.ring = num;
0691           break;
0692         case 3:
0693           adr.mask.chamber = mask;
0694           adr.chamber = num;
0695           break;
0696         case 4:
0697           adr.mask.layer = mask;
0698           adr.layer = num;
0699           break;
0700         case 5:
0701           adr.mask.cfeb = mask;
0702           adr.cfeb = num;
0703           break;
0704         case 6:
0705           adr.mask.hv = mask;
0706           adr.hv = num;
0707       }
0708     }
0709 
0710     return true;
0711   }
0712 
0713 }  // namespace cscdqm