////////////////////////////////////////////////////////////////////////////// // // $Id: $ // //*-- Author : Witold Przygoda (przygoda@psja1.if.uj.edu.pl) //*-- Revised : Martin Jurkovic 2010 // //_HADES_CLASS_DESCRIPTION ////////////////////////////////////////////////////////////////////////////// // // HRichPadTab // // These classes contain definition of array of pads. // // ////////////////////////////////////////////////////////////////////////////// #include "TClonesArray.h" #include "hades.h" #include "hparamlist.h" #include "hrichpad.h" #include "hrichpadcorner.h" #include "hrichpadtab.h" #include "hspectrometer.h" #include using namespace std; ClassImp(HRichPadTab) HRichPadTab::HRichPadTab() : HParCond() { clear(); fPadsArray = NULL; } HRichPadTab::~HRichPadTab() { deletePads(); } void HRichPadTab::clear() { fActivePadsNr = 0; // will be a part of a parameter container and initialized from there fPadsLongestRow = 76; fMiddlePad = 7344; fPadsLongestRowMiddle = 0.; } void HRichPadTab::deletePads() { if (NULL != fPadsArray) { fPadsArray->Delete(); delete fPadsArray; fPadsArray = NULL; } clear(); } Bool_t HRichPadTab::getParams(HParamList* l) { // padParams: array with size (numberOfPads * 11) in sector 1 // 11 numbers for each pad: // 1: pad_pos_id = colNumber*100 + rowNumber // 2: theta // 3: phi (in sector 1) // 4..11 x and y of the 4 pad corners // theta and the pad corners are identical in each sector // for phi the sector rotation (relative to sector 1) must be added //------------------------------------------------------------------------------- UInt_t address = 0; UInt_t ret = 0; if ((RICH_MAX_COLS * RICH_MAX_ROWS) != (ret = createPads())) { Error("getParams", "Pointer to fPadsArray is NULL or has wrong size (%i instead of %i).", ret, (RICH_MAX_COLS * RICH_MAX_ROWS)); return kFALSE; } if (NULL == l) return kFALSE; if (!l->fill("fPadParams", &fPadParams)) return kFALSE; // this is dummy initialisation of all pads structure for (UInt_t i = 0; i < (RICH_MAX_COLS * RICH_MAX_ROWS); ++i) { HRichPad *pad = new HRichPad; pad->setPadNr(i); pad->CalcNrtoXY(RICH_MAX_COLS); pad->setPadActive(0); pad->setPadFlag(0); pad->setAmplitFraction(0.); for (Int_t j = 0; j < 6; ++j) { pad->setPhi(j, 0.0); } pad->setTheta(0.0); setPad(pad, i); delete pad; } // We have 11 items per pad for (Int_t i = 0; i < fPadParams.GetSize() / 11; ++i) { address = static_cast(fPadParams[11*i+0]); HRichPad *pad = getPad(static_cast(address / 100), address % 100); pad->setPadActive(1); fActivePadsNr++; pad->setTheta(fPadParams[11*i+1]); for (Int_t j = 0; j < 6; ++j) { pad->setPhi(j, 60 * j + fPadParams[11*i+2]); if (pad->getPhi(j) > 360) { pad->setPhi(j, pad->getPhi(j) - 360); } } for (Int_t j = 0; j < 4; ++j) { HRichPadCorner *padcorner = new HRichPadCorner; padcorner->setX(fPadParams[11*i+3+2*j]); padcorner->setY(fPadParams[11*i+4+2*j]); padcorner->setCornerNr(j); pad->addCorner(padcorner); } } // eof reading data initParameters(); return kTRUE; } void HRichPadTab::printParams() { cout << "HRichPadTab" << endl; cout << "==========================================" << endl; cout << "fPadParams " << endl; for (Int_t i = 0; i < fPadParams.GetSize(); i += 11) { cout << " "; for (Int_t j = 0; j < 11; ++j) { cout << fPadParams[i+j] << " "; } cout << endl; } cout << endl; } void HRichPadTab::putParams(HParamList* l) { if (NULL == l) return; l->add("fPadParams", fPadParams); } Bool_t HRichPadTab::initParameters() { // all this calculations can be a part of the pad params in the future Float_t xcor = 0.; Float_t ycor = 0.; Float_t xmin = 0.; Float_t ymin = 0.; Float_t xmax = 0.; Float_t ymax = 0.; Float_t x1 = 0.; Float_t x2 = 0.; Float_t y1 = 0.; Float_t y2 = 0.; Float_t a = 0.0; Float_t b = 0.0; Bool_t AnalyticDigitisation = kTRUE; Int_t n1 = 0; Int_t n2 = 0; Int_t Area0 = 0; Int_t Area1 = 0; HRichPad* pPad = NULL; HRichPadCorner* pCorner = NULL; for (Int_t i = 0; i < (RICH_MAX_COLS * RICH_MAX_ROWS); ++i) { AnalyticDigitisation = kTRUE; pPad = getPad(i); // the loop sets minimum and maximum (in x and y) for given pad for (Int_t j = 0; j < pPad->getCornersNr(); ++j) { pCorner = pPad->getCorner(j); xcor = pCorner->getX(); ycor = pCorner->getY(); if (j == 0) { xmin = xmax = xcor; ymin = ymax = ycor; } if (xcor < xmin) xmin = xcor; if (xcor > xmax) xmax = xcor; if (ycor < ymin) ymin = ycor; if (ycor > ymax) ymax = ycor; } pPad->setXmin(xmin); pPad->setYmin(ymin); pPad->setXmax(xmax); pPad->setYmax(ymax); // the loop checks if analytical formula can be used during digitisation if (pPad->getCornersNr() != 4) { AnalyticDigitisation = kFALSE; } else { for (Int_t j = 0; j < pPad->getCornersNr(); ++j) { pPad->getCorner(j)->getXY(&x1, &y1); if (j + 1 < pPad->getCornersNr()) { pPad->getCorner(j + 1)->getXY(&x2, &y2); } else { pPad->getCorner(0)->getXY(&x2, &y2); } if (x1 != x2 && y1 != y2) AnalyticDigitisation = kFALSE; } } if (AnalyticDigitisation) { pPad->setPadFlag(1); } else { pPad->setPadFlag(2); } // calculation of flag area for (Int_t j = 0; j < pPad->getCornersNr(); ++j) { pPad->getCorner(j)->getXY(&x1, &y1); n1 = pPad->getCorner(j)->getCornerNr(); if (j + 1 < pPad->getCornersNr()) { pPad->getCorner(j + 1)->getXY(&x2, &y2); n2 = pPad->getCorner(j + 1)->getCornerNr(); } else { pPad->getCorner(0)->getXY(&x2, &y2); n2 = pPad->getCorner(0)->getCornerNr(); } Area0 = Area1 = 0; if (x1 == x2) { for (Int_t k = 0; k < pPad->getCornersNr(); ++k) { if (pPad->getCorner(k)->getCornerNr() != n1 && pPad->getCorner(k)->getCornerNr() != n2) { if (pPad->getCorner(k)->getX() > x1) Area1++; if (pPad->getCorner(k)->getX() < x1) Area0++; } } if (Area1 + 2 == pPad->getCornersNr()) { pPad->getCorner(j)->setAreaFlag(1); } else { if (Area0 + 2 == pPad->getCornersNr()) { pPad->getCorner(j)->setAreaFlag(0); } else { Error("initParameters", "1...Inconsistency in pads corners coordinates! Pad: %d", pPad->getPadNr()); return kFALSE; } } } else if (y1 == y2) { for (Int_t k = 0; k < pPad->getCornersNr(); ++k) { if (pPad->getCorner(k)->getCornerNr() != n1 && pPad->getCorner(k)->getCornerNr() != n2) { if (pPad->getCorner(k)->getY() > y1) Area1++; if (pPad->getCorner(k)->getY() < y1) Area0++; } } if (Area1 + 2 == pPad->getCornersNr()) { pPad->getCorner(j)->setAreaFlag(1); } else { if (Area0 + 2 == pPad->getCornersNr()) { pPad->getCorner(j)->setAreaFlag(0); } else { Error("initParameters", "2...Inconsistency in pads corners coordinates! Pad: %d", pPad->getPadNr()); return kFALSE; } } } else { a = (y2 - y1) / (x2 - x1); b = (x2 * y1 - x1 * y2) / (x2 - x1); for (Int_t k = 0; k < pPad->getCornersNr(); ++k) { if (pPad->getCorner(k)->getCornerNr() != n1 && pPad->getCorner(k)->getCornerNr() != n2) { if (pPad->getCorner(k)->getY() > a * pPad->getCorner(k)->getX() + b) Area1++; if (pPad->getCorner(k)->getY() < a * pPad->getCorner(k)->getX() + b) Area0++; } } if (Area1 + 2 == pPad->getCornersNr()) { pPad->getCorner(j)->setAreaFlag(1); } else { if (Area0 + 2 == pPad->getCornersNr()) { pPad->getCorner(j)->setAreaFlag(0); } else { Error("initParameters", "3...Inconsistency in pads corners coordinates! Pad: %d", pPad->getPadNr()); return kFALSE; } } } } // end of loop over all corners pPad->calcPadCenter(); } // eof loop over all pads return kTRUE; } Int_t HRichPadTab::createPads() { deletePads(); fPadsArray = new TClonesArray("HRichPad", (RICH_MAX_COLS * RICH_MAX_ROWS)); return (fPadsArray) ? (RICH_MAX_COLS * RICH_MAX_ROWS) : 0; } void HRichPadTab::setPad(HRichPad* pPad, UInt_t col, UInt_t row) { setPad(pPad, calcAddr(col, row)); } void HRichPadTab::setPad(HRichPad* pPad, UInt_t padNr) { HRichPad* pNewPad = NULL; pNewPad = static_cast(getSlot(padNr)); pNewPad = new(pNewPad) HRichPad; *pNewPad = *pPad; } HRichPad* HRichPadTab::getPad(UInt_t col, UInt_t row) { if ((col < 0) || (col >= RICH_MAX_COLS)) return NULL; if ((row < 0) || (row >= RICH_MAX_ROWS)) return NULL; return getPad(calcAddr(col, row)); } HRichPad* HRichPadTab::getPad(Float_t Xpos, Float_t Ypos) { UInt_t i = 0; UInt_t j = 0; UInt_t nPadAddr = 0; UInt_t nHit = 0; if (Xpos < fPadsLongestRowMiddle) { for (nPadAddr = fPadsLongestRow * RICH_MAX_COLS; nPadAddr < fMiddlePad; nPadAddr++) { if (getPad(nPadAddr)->getPadActive() == kTRUE) { if (!getPad(nPadAddr)->isOutX(Xpos)) { nHit = 1; break; } } } } else { for (nPadAddr = fMiddlePad; nPadAddr < fPadsLongestRow * RICH_MAX_COLS + RICH_MAX_COLS; nPadAddr++) { if (getPad(nPadAddr)->getPadActive() == kTRUE) { if (!getPad(nPadAddr)->isOutX(Xpos)) { nHit = 1; break; } } } } if (nHit == 0) { return NULL; } nHit = 0; i = nPadAddr % RICH_MAX_COLS; for (j = 0; j < RICH_MAX_ROWS; j++) { if (NULL == getPad(i, j)) { Error("getPad", "Pad not found"); continue; } if (getPad(i, j)->getPadActive() == kTRUE) { if (!getPad(i, j)->isOut(Xpos, Ypos)) { nHit = 1; break; } } } if (nHit == 0) { return NULL; } return getPad(i, j); } Bool_t HRichPadTab::isOut(UInt_t X, UInt_t Y) { if ((X < 0) || (X >= RICH_MAX_COLS)) return kTRUE; if ((Y < 0) || (Y >= RICH_MAX_ROWS)) return kTRUE; return kFALSE; } TObject*& HRichPadTab::getSlot(Int_t nIndx) { return (fPadsArray->operator[](nIndx)); } TObject* HRichPadTab::getObject(Int_t nIndx) { return fPadsArray->At(nIndx); } void HRichPadTab::Streamer(TBuffer &R__b) { // Stream an object of class HRichPadTab. if (R__b.IsReading()) { Version_t R__v = R__b.ReadVersion(); if (R__v) { } HParSet::Streamer(R__b); R__b >> fActivePadsNr; R__b >> fPadsLongestRow; R__b >> fMiddlePad; R__b >> fPadsLongestRowMiddle; // this is dummy initialisation of all pads structure if (createPads()) { for (UInt_t i = 0; i < (RICH_MAX_COLS * RICH_MAX_ROWS); i++) { HRichPad *pad = new HRichPad; pad->setPadNr(i); pad->CalcNrtoXY(RICH_MAX_COLS); pad->setPadActive(0); pad->setPadFlag(0); pad->setAmplitFraction(0.); setPad(pad, i); delete pad; } fPadsArray->Streamer(R__b); } initParameters(); } else { R__b.WriteVersion(HRichPadTab::IsA()); HParSet::Streamer(R__b); R__b << fActivePadsNr; R__b << fPadsLongestRow; R__b << fMiddlePad; R__b << fPadsLongestRowMiddle; fPadsArray->Streamer(R__b); } }