00001
00002
00003
00170 #include "IORawData/Ecal2004TBInputService/interface/H4Geom.h"
00171 #include <iostream>
00172
00173 using namespace std;
00174
00175 const int H4Geom::crystalChannelMap[5][5] = {
00176 { 4, 5, 14, 15, 24},
00177 { 3, 6, 13, 16, 23},
00178 { 2, 7, 12, 17, 22},
00179 { 1, 8, 11, 18, 21},
00180 { 0, 9, 10, 19, 20}
00181 };
00182
00183 const int H4Geom::crystalMap[25] = {
00184 340, 255, 170, 85, 0,
00185 1, 86, 171, 256, 341,
00186 342, 257, 172, 87, 2,
00187 3, 88, 173, 258, 343,
00188 344, 259, 174, 89, 4
00189 };
00190
00191 H4Geom::GeomPeriod_t H4Geom::geometry_ = H4Geom::Undef;
00192
00193
00194 H4Geom::H4Geom()
00195 {
00196 GeomPeriod_t ForFilesConversion;
00197 ForFilesConversion = Automn2004;
00198 H4Geom::SetGeomPeriod(ForFilesConversion);
00199 }
00200
00202 H4Geom::~H4Geom()
00203 { }
00204
00206 bool H4Geom::init()
00207 {
00208
00209
00210
00211
00212
00213 return true;
00214 }
00215
00218 int H4Geom::getSMCrystalNumber(int tower, int crystal) const
00219 {
00220 if (!IsGeomPeriodDefined()) abort();
00221 if (geometry_ == H4Geom::Spring2004) {
00222 int smCrystalNbr = 0;
00223 if ((crystal/5)%2 == 0)
00224 smCrystalNbr = kCrystalsPerTower -
00225 int(crystal/kCardsPerTower)*kChannelsPerCard -
00226 crystal%kChannelsPerCard + (tower - 1)*kCrystalsPerTower;
00227 else
00228 smCrystalNbr = kCrystalsPerTower + 1 -
00229 (int(crystal/kCardsPerTower) + 1)*kChannelsPerCard +
00230 crystal%kChannelsPerCard + (tower - 1)*kCrystalsPerTower;
00231 return smCrystalNbr;
00232 } else if (geometry_ == H4Geom::Automn2004) {
00233 int eta = (tower - 1)/kTowersInPhi*kCardsPerTower;
00234 int phi = (tower - 1)%kTowersInPhi*kChannelsPerCard;
00235 if (rightTower(tower))
00236 eta += crystal/kCardsPerTower;
00237 else
00238 eta += (kCrystalsPerTower - 1 - crystal)/kCardsPerTower;
00239 if (rightTower(tower) && (crystal/kCardsPerTower)%2 == 1 ||
00240 !rightTower(tower) && (crystal/kCardsPerTower)%2 == 0)
00241 phi += (kChannelsPerCard - 1 - crystal%kChannelsPerCard);
00242 else
00243 phi += crystal%kChannelsPerCard;
00244 return eta*kChannelsPerCard*kTowersInPhi + phi + 1;
00245 } else {
00246 int towerId = tower - 1;
00247 int line = towerId%4;
00248 int column = towerId/4;
00249 int lowerRight = 5*line*85 + column*5;
00250 if (rightTower(tower))
00251 return lowerRight+crystalMap[crystal];
00252 else
00253 return lowerRight+crystalMap[24-crystal];
00254 }
00255 }
00256
00257
00260 void H4Geom::getTowerCrystalNumber(int &tower, int &crystal, int smCrystal) const
00261 {
00262 if (!IsGeomPeriodDefined()) abort();
00263 if (geometry_ == H4Geom::Spring2004) {
00264
00265 tower = (smCrystal - 1)/kCrystalsPerTower + 1;
00266 smCrystal -= (tower - 1)*kCrystalsPerTower;
00267 if (((smCrystal - 1)/kCardsPerTower)%2 == 0)
00268 crystal = (kCardsPerTower -
00269 int((smCrystal - 1)/kCardsPerTower))*kCardsPerTower -
00270 (smCrystal - 1)%kCardsPerTower - 1;
00271 else
00272 crystal = (kCardsPerTower - 1 -
00273 int((smCrystal - 1)/kCardsPerTower))*kCardsPerTower +
00274 (smCrystal - 1)%kCardsPerTower;
00275 return;
00276 } else if (geometry_ == H4Geom::Automn2004) {
00277 int eta = (smCrystal - 1)/(kChannelsPerCard*kTowersInPhi);
00278 int phi = (smCrystal - 1)%(kChannelsPerCard*kTowersInPhi);
00279 tower = eta/kCardsPerTower*kTowersInPhi + phi/kChannelsPerCard + 1;
00280 if (rightTower(tower)) {
00281 crystal = (eta%kCardsPerTower)*kChannelsPerCard;
00282 if ((eta%kChannelsPerCard)%2 == 0)
00283 crystal += phi%kChannelsPerCard;
00284 else
00285 crystal += kChannelsPerCard - 1 - phi%kChannelsPerCard;
00286 } else {
00287 crystal = (kCardsPerTower - 1 - eta%kCardsPerTower)*kChannelsPerCard;
00288 if ((eta%kChannelsPerCard)%2 == 0)
00289 crystal += kChannelsPerCard - 1 - phi%kChannelsPerCard;
00290 else
00291 crystal += phi%kChannelsPerCard;
00292 }
00293 } else {
00294 int line = smCrystal/85;
00295 int cInLine = smCrystal%85;
00296
00297 tower= 1 + (cInLine/5) * 4 + line/5;
00298 crystal = crystalChannelMap[line%5][cInLine%5];
00299 if (leftTower(tower)) crystal = 24-crystal ;
00300 }
00301 return;
00302 }
00303
00304
00309 int H4Geom::getTowerCrystalNumber(int smTowerNb, int crystalNbGeom) const
00310 {
00311 if (crystalNbGeom < 0 || crystalNbGeom >= kCrystalsPerTower) return -1 ;
00312 int column = crystalNbGeom/kCardsPerTower;
00313 int line = crystalNbGeom%kChannelsPerCard;
00314 int crystal = crystalChannelMap[line][column];
00315 if (leftTower(smTowerNb)) crystal = kCrystalsPerTower - 1 - crystal;
00316 return crystal;
00317 }
00318
00319
00322 void H4Geom::getCrystalCoord(int &eta, int &phi, int smCrystal) const
00323 {
00324 if (geometry_ == H4Geom::Spring2004) {
00325 eta = (smCrystal - 1)/kChannelsPerCard;
00326 phi = kChannelsPerCard - 1 -
00327 ((smCrystal - 1)%kCrystalsPerTower)%kChannelsPerCard;
00328 } else if (geometry_ == H4Geom::Automn2004) {
00329 eta = (smCrystal - 1)/(kChannelsPerCard*kTowersInPhi);
00330 phi = (smCrystal - 1)%(kChannelsPerCard*kTowersInPhi);
00331 } else {
00332 eta = smCrystal%kCrystalsInEta;
00333 phi = smCrystal/kCrystalsInEta;
00334 }
00335 }
00336
00337
00339 int H4Geom::getSMCrystalFromCoord(int eta, int phi) const
00340 {
00341 if (geometry_ == H4Geom::Spring2004) {
00342 if (eta >= 9 || eta < 0 || phi >= 4 || phi < 0)
00343 return -1;
00344 return eta*kCardsPerTower + (kChannelsPerCard - phi);
00345 }
00346 if (eta < 0 || eta >= kCrystalsInEta || phi < 0 || phi >= kCrystalsInPhi)
00347 return -1;
00348 else {
00349 if (geometry_ == H4Geom::Automn2004)
00350 return eta*kChannelsPerCard*kTowersInPhi + phi + 1;
00351 else
00352 return eta + kCrystalsInEta*phi;
00353 }
00354 }
00355
00356
00360 int H4Geom::getLeft(int smCrystal) const
00361 {
00362 if (!IsGeomPeriodDefined()) abort();
00363 if (geometry_ == H4Geom::Spring2004) {
00364 smCrystal += kChannelsPerCard;
00365 if (smCrystal > 2*kCrystalsPerTower || smCrystal < 1) return -1;
00366 return smCrystal;
00367 } else if (geometry_ == H4Geom::Automn2004) {
00368 smCrystal += kCrystalsInPhi;
00369 if (smCrystal > kCrystals) return -1;
00370 return smCrystal;
00371 } else {
00372 smCrystal++;
00373 if (!(smCrystal % kCrystalsInEta)) return -1;
00374 if (smCrystal >= kCrystals || smCrystal < 0) return -1;
00375 return smCrystal;
00376 }
00377 }
00378
00379
00383 int H4Geom::getRight(int smCrystal) const
00384 {
00385 if (!IsGeomPeriodDefined()) abort();
00386 if (geometry_ == H4Geom::Spring2004) {
00387 smCrystal -= kChannelsPerCard;
00388 if (smCrystal > 2*kCrystalsPerTower || smCrystal < 1) return -1;
00389 return smCrystal;
00390 } else if (geometry_ == H4Geom::Automn2004) {
00391 smCrystal -= kCrystalsInPhi;
00392 if (smCrystal < 0) return -1;
00393 return smCrystal;
00394 } else {
00395 smCrystal--;
00396 if (smCrystal % kCrystalsInEta == kCrystalsInEta - 1) return -1;
00397 if (smCrystal >= kCrystals || smCrystal < 0) return -1;
00398 return smCrystal;
00399 }
00400 }
00401
00402
00406 int H4Geom::getUpper(int smCrystal) const{
00407 if (!IsGeomPeriodDefined()) abort();
00408 if (geometry_ == H4Geom::Spring2004) {
00409 smCrystal--;
00410 if (smCrystal > 2*kCrystalsPerTower || smCrystal < 1) return -1;
00411 return smCrystal;
00412 } else if (geometry_ == H4Geom::Automn2004) {
00413 if ((smCrystal - 1)%kCrystalsInPhi == 0) return -1;
00414 smCrystal--;
00415 return smCrystal;
00416 } else {
00417 smCrystal += kCrystalsInEta;
00418 if (smCrystal >= kCrystals || smCrystal < 0) return -1;
00419 return smCrystal;
00420 }
00421 }
00422
00423
00427 int H4Geom::getLower(int smCrystal) const
00428 {
00429 if (!IsGeomPeriodDefined()) abort();
00430 if (geometry_ == H4Geom::Spring2004) {
00431 smCrystal ++;
00432 if (smCrystal > 2*kCrystalsPerTower || smCrystal < 1) return -1;
00433 return smCrystal;
00434 } else if (geometry_ == H4Geom::Automn2004) {
00435 if (smCrystal%kCrystalsInPhi == 0) return -1;
00436 smCrystal++;
00437 return smCrystal;
00438 } else {
00439 smCrystal -= kCrystalsInEta;
00440 if (smCrystal >= kCrystals || smCrystal < 0) return -1;
00441 return smCrystal;
00442 }
00443 }
00444
00445
00449 void H4Geom::mvLeft(int &eta, int &phi) const
00450 {
00451 if (eta >= kCrystalsInEta)
00452 std::cout << "H4Geom::mvLeft: eta is too large " << eta << std::endl;
00453 eta++;
00454 }
00455
00459 void H4Geom::mvRight(int &eta, int &phi) const
00460 {
00461 if (eta < 0)
00462 std::cout << "H4Geom::mvRight: eta is too small " << eta << std::endl;
00463 eta--;
00464 }
00465
00469 void H4Geom::mvUp(int &eta, int &phi) const
00470 {
00471 if (phi >= kCrystalsInPhi)
00472 std::cout << "H4Geom::mvUp: phi is too large " << phi << std::endl;
00473 phi++;
00474 }
00475
00476
00480 void H4Geom::mvDown(int &eta, int &phi) const
00481 {
00482 if (phi < 0)
00483 std::cout << "H4Geom::mvDown: phi is too small " << phi << std::endl;
00484 phi--;
00485 }
00486
00487
00494
00510 void H4Geom::getTower(int * tower, int towerNb, std::string order) const
00511 {
00512 if (!IsGeomPeriodDefined()) abort();
00513 if (order == "readout") {
00514 for (int crystalNb = 0; crystalNb < kCrystalsPerTower; crystalNb++)
00515 tower[crystalNb] = getSMCrystalNumber(towerNb, crystalNb);
00516 } else {
00517 int towerId = towerNb - 1;
00518 int line = towerId%kTowersInPhi;
00519 int column = towerId/kTowersInPhi;
00520 if (geometry_ == H4Geom::Automn2004) {
00521 int smLowerRight = column*kCardsPerTower*kCrystalsInPhi +
00522 (line + 1)*kChannelsPerCard;
00523 for (int i = 0; i < kCrystalsPerTower; i++)
00524 tower[i] = smLowerRight - i%kChannelsPerCard +
00525 i/kChannelsPerCard*kCrystalsInPhi;
00526 } else {
00527 int smLowerRight = kChannelsPerCard*line*kCrystalsInEta +
00528 column*kCardsPerTower;
00529 for (int i = 0; i < kCrystalsPerTower; i++)
00530 tower[i] = i%kChannelsPerCard * kCrystalsInEta +
00531 i/kChannelsPerCard + smLowerRight;
00532 }
00533 }
00534 return;
00535 }
00536
00537
00544
00560 void H4Geom::getVFE(int * VFE, int smCrystal, std::string order) const
00561 {
00562 int towerNb, crystalNb;
00563 getTowerCrystalNumber(towerNb, crystalNb, smCrystal);
00564 int VFEnb = crystalNb/kChannelsPerCard;
00565 if (order == "readout") {
00566 for (crystalNb = 0; crystalNb < kChannelsPerCard; crystalNb++)
00567 VFE[crystalNb] = getSMCrystalNumber(towerNb,
00568 kChannelsPerCard*VFEnb+crystalNb);
00569 } else {
00570 int eta, phi;
00571 getCrystalCoord(eta, phi, smCrystal);
00572 int smLower = eta+85*5*(phi/5);
00573 for (int i = 0; i < 5; i++)
00574 VFE[i] = i*85 + smLower;
00575 }
00576 }
00577
00583
00604 void H4Geom::getWindow(int * window, int smCrystal, int width, int height) const
00605 {
00606 if (width <= 0 || width%2 == 0) {
00607 std::cout << "H4Geom::getWindow, width should be >0 and odd!" << std::endl;
00608 return;
00609 }
00610 if (height <= 0 || height%2 == 0) {
00611 std::cout << "H4Geom::getWindow, height should be >0 and odd!"
00612 << std::endl;
00613 return;
00614 }
00615 int eta, phi;
00616 getCrystalCoord(eta, phi, smCrystal);
00617
00618 int eta0 = eta - (width - 1)/2;
00619 int phi0 = phi - (height - 1)/2;
00620 int index = 0;
00621 eta = eta0;
00622 phi = phi0;
00623 for (int i = 0; i < width; i++) {
00624 for (int j = 0; j < height; j++) {
00625 window[index] = getSMCrystalFromCoord(eta, phi);
00626 phi++;
00627 index++;
00628 }
00629 eta++;
00630 phi = phi0;
00631 }
00632 }
00633
00634
00637
00653 bool H4Geom::rightTower(int tower) const
00654 {
00655 if (!IsGeomPeriodDefined()) abort();
00656 if (geometry_ == H4Geom::Automn2004) {
00657 if ((tower - 1)/kTowersInPhi < 3 ||
00658 ((tower - 1)/kTowersInPhi - 3)%4 >= 2)
00659 return false;
00660 else
00661 return true;
00662 }
00663 if ((tower>12 && tower<21) || (tower>28 && tower<37) ||
00664 (tower>44 && tower<53) || (tower>60 && tower<69))
00665 return true;
00666 else
00667 return false;
00668 }
00669
00672
00688 bool H4Geom::leftTower(int tower) const
00689 {
00690 return !rightTower(tower);
00691 }
00692
00693 void H4Geom::SetGeomPeriod(GeomPeriod_t geometry)
00694 {
00695 geometry_ = geometry;
00696 }
00697
00698 bool H4Geom::IsGeomPeriodDefined() const {
00699 if (geometry_ == H4Geom::Undef) {
00700 std::cout << "Class H4Geom : geometry is not defined. You should call in"
00701 << " your program H4Geom::init (and fill the [Geometry] section"
00702 << " of your config file) or call H4Geom::SetGeomPeriod."
00703 << std::endl;
00704 return false;
00705 }
00706 return true;
00707 }