/** CbmMuchSegmentation.cxx *@author Mikhail Ryzhinskiy *@since 20.06.07 *@version 1.0 ** ** class for making parameter file for MUCH digitizer ** **/ #include #include #include #include #include "CbmMuchSegmentation.h" #include "TCanvas.h" #include "TString.h" #include "TArrow.h" #include "TEllipse.h" using std::cout; using std::endl; using std::ios; using std::vector; // ----- Default constructor ------------------------------------------ CbmMuchSegmentation::CbmMuchSegmentation() { // Set default values fDigiFileName = "much.digi.par"; // name of the digitizer parameter file fNLayers = 6; // number of layers fNChannels.assign(fNLayers, 128); // number of channels per sector // Set angle between stations in each layer Double_t angle[] = {10, 10, 10, 10, 10, 10}; fAngle.assign(angle, angle+fNLayers); // Set default values for minimal pad size Double_t padWidth[] = {0.14, 0.28, 0.28, 0.56, 0.56, 0.56}; Double_t padLength[] = {0.28, 0.28, 0.56, 0.56, 1.12, 1.12}; fMinPadWidth.assign(padWidth, padWidth + fNLayers); fMinPadLength.assign(padLength, padLength + fNLayers); // Set default values for minimal sector size Double_t secWidth[] = {2.24, 2.24, 4.48, 4.48, 8.96, 8.96}; Double_t secLength[] = {2.24, 4.48, 4.48, 8.96, 8.96, 8.96}; fMinSectorWidth.assign(secWidth, secWidth + fNLayers); fMinSectorLength.assign(secLength, secLength + fNLayers); // Set default values for minimal resolution [microns] Double_t sigmaX[] = {0., 0., 0., 0., 0., 0.}; Double_t sigmaY[] = {0., 0., 0., 0., 0., 0.}; for(int i=0;Double_t(i) vrad1(rad1, rad1 + sizeof(rad1)/sizeof(Double_t)); vector vrad2(rad2, rad2 + sizeof(rad2)/sizeof(Double_t)); vector vrad3(rad3, rad3 + sizeof(rad3)/sizeof(Double_t)); vector vrad4(rad4, rad4 + sizeof(rad4)/sizeof(Double_t)); vector vrad5(rad5, rad5 + sizeof(rad5)/sizeof(Double_t)); vector vrad6(rad6, rad6 + sizeof(rad6)/sizeof(Double_t)); fRadia[0] = vrad1; fRadia[1] = vrad2; fRadia[2] = vrad3; fRadia[3] = vrad4; fRadia[4] = vrad5; fRadia[5] = vrad6; } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- CbmMuchSegmentation::~CbmMuchSegmentation() { vector >().swap(fRadia); vector().swap(fMinPadWidth); vector().swap(fMinPadLength); vector().swap(fMinSectorWidth); vector().swap(fMinSectorLength); vector().swap(fMinSigmaX); vector().swap(fMinSigmaY); vector().swap(fAngle); vector().swap(fNRegions); vector().swap(fNChannels); } // ------------------------------------------------------------------------- // ----- SetAngle method ---------------------------------------------- void CbmMuchSegmentation::SetAngle(Int_t iLayer, Double_t angle){ if(iLayer < 1 || iLayer > fNLayers) { cout << "The number of the layer is out of available range." << endl; return; } fAngle[iLayer-1] = angle; } // ------------------------------------------------------------------------- // ----- SetMinSigmaX method ------------------------------------------ void CbmMuchSegmentation::SetMinSigmaX(Int_t iLayer, Double_t sigmaX){ if(iLayer < 1 || iLayer > fNLayers) { cout << "The number of the layer is out of available range." << endl; return; } // Lower limit for resolution is 100 microns if(sigmaX < 100.) { cout << "Too low resolution on X is set." << endl; return; } fMinSigmaX[iLayer-1] = sigmaX; // Calculate corresponding pad size [cm] fMinPadWidth[iLayer-1] = fMinSigmaX[iLayer-1]*3.464101*1e-4; } // ------------------------------------------------------------------------- // ----- SetMinSigmaY method ------------------------------------------ void CbmMuchSegmentation::SetMinSigmaY(Int_t iLayer, Double_t sigmaY){ if(iLayer < 1 || iLayer > fNLayers) { cout << "\nThe number of the layer is out of available range." << endl; return; } // Upper limit for resolution is 100 microns if(sigmaY < 100.) { cout << "Too low resolution on Y is set." << endl; return; } fMinSigmaY[iLayer-1] = sigmaY; // Calculate corresponding pad size [cm] fMinPadLength[iLayer-1] = fMinSigmaY[iLayer-1]*3.464101*1e-4; } // ------------------------------------------------------------------------- // ----- SegmentMuch method ------------------------------------------- void CbmMuchSegmentation::SegmentMuch(){ ofstream digiFile(fDigiFileName, ios::out); digiFile << "#################################################################\n" << "# Digitisation parameters for MuCh\n" << "# Adjust this info according to your needs. For geometry file ???.geo\n" << "# How many station of what type\n" << "# \n" << "# Format:\n" << "# StationNr global_rot nSectors\n" << "# sectNr \t iType \t x0 \t y0 \t angle \t lx \t ly \t dx \t dy \n" << "#################################################################\n" << "[CbmMuchDigiPar]" << endl; digiFile.close(); // Make segmentation for each station for(Int_t iLayer = 0; iLayer dy){ ratio = dx/dy; n = (int)(log(ratio)/0.693147); dx = pow(2.,n)*dy; k = (int)(n/2); lx = 8/pow(2.,k)*dx; ly = 16*pow(2.,k)*dy; } else if(dx < dy){ ratio = dy/dx; n = (int)(log(ratio)/0.693147); dy = pow(2.,n)*dx; k = (int)((n+1)/2); lx = 8*pow(2.,k)*dx; ly = 16/pow(2.,k)*dy; } fMinPadWidth[iLayer] = dx; fMinPadLength[iLayer] = dy; fMinSectorWidth[iLayer] = lx; fMinSectorLength[iLayer] = ly; // cout << "****************************************" << endl; // cout << "layer " << iLayer // << "\tdx=" << dx // << "\tdy=" << dy // << "\tlx=" << lx // << "\tly=" << ly // << endl; // cout << "****************************************" << endl; } // ------------------------------------------------------------------------- // ----- MakeSegmentation method --------------------------------------- void CbmMuchSegmentation::MakeSegmentation(Int_t iLayer){ TString name("layer"); name += iLayer + 1; TCanvas* canvas = new TCanvas(name, name, 900,900); //************** Fill regions with sectors (begin) *******************// vector nSectors(fNRegions[iLayer], 0); // number of sectors in each region vector paves; // objects representing sectors vector secLx(fNRegions[iLayer]); // width of sectors in each region vector secLy(fNRegions[iLayer]); // length of sectors in each region // Define sector size for each region SetSectorSizes(fNRegions[iLayer], fMinSectorWidth[iLayer], fMinSectorLength[iLayer], secLx, secLy); // Fill regions with sectors int nOld = 0; int nNew = 0; for(int i=0; i=0; i--){ if(id!=0 && i==fNRegions[iLayer]-1) continue; nOld = nNew; double delta = id*fMinSectorLength[iLayer]; //double delta = (i>fNRegions[iLayer] - 3) ? 0 : fMinSectorLength[iLayer]; DrawPaves(fRadia[iLayer][i], fRadia[iLayer][i+1] + delta, secLx[i], secLy[i], paves, i+2, kGaps); nNew = (int)paves.size(); nSectors[i] += nNew - nOld; } } //************** Fill regions with sectors (end) *********************// //************** Draw regions and coordinates (begin) ***************// Int_t xMax = (Int_t)(fRadia[iLayer][fNRegions[iLayer]]*1.5); Int_t xMin = -xMax; Int_t yMin = xMin; Int_t yMax = xMax; gPad->Range(xMin,yMin,xMax,yMax); gPad->SetFillColor(0); // Draw circled regions for(Int_t i = 0; i<=fNRegions[iLayer];i++){ // Draw regions TEllipse* el = new TEllipse(0,0,fRadia[iLayer][i], fRadia[iLayer][i]); el->SetFillColor(0); el->Draw(); } // Draw coordinate system TArrow* arrowX = new TArrow(xMin,0,xMax,0,0.03,"|>"); TArrow* arrowY = new TArrow(0,yMin,0,yMax,0.03,"|>"); arrowX->SetAngle(30); arrowY->SetAngle(30); arrowX->Draw(); arrowY->Draw(); //************** Draw regions and coordinates (end) ******************// //************** Write parameters in ASCII file (begin) **************// CreateAsciiInputPads(iLayer, 1, paves); //************** Write parameters in ASCII file (end) ****************// //************** Save graphics (begin) *******************************// TString epsFileName(name); epsFileName += ".eps"; canvas->Print(epsFileName.Data()); canvas->Close(); //************** Save graphics (end) *********************************// } // ------------------------------------------------------------------------- // ----- SetSectorSizes method ----------------------------------------- void CbmMuchSegmentation::SetSectorSizes(int nRegions, double minSecLx, double minSecLy, vector& secLx, vector& secLy){ for(Int_t i=0;i& paves, Int_t iColor, PlainPart iPart){ // Define number of rows and columns for the region Int_t nRows = (Int_t)((rad2 + 1e-5)/height); Int_t nColumns; ++nRows *= 2; if(fabs(2.*width - height) < 1e-5) nColumns = 2*nRows; else if(fabs(width - height) < 1e-5) nColumns = nRows; else{ cout << width << "\t" << height << endl; cout << "Error occured. Exiting...\n"; return; } // Fill the region Double_t x1,x2,y1,y2; // current coordianates of the card Double_t regionSize = nRows*height; // size of the region side [cm] // Int_t n= ((nRows%2)==0) ? nRows/2 : nRows/2 + 1; assert(nRows%2 == 0); Int_t n = nRows/2; Int_t k = 0; for(int i = 0; i0) k = i-1; for(int j = k; j& paves, Int_t iColor){ TVector2 p1(x1+0.2,y1+0.2); TVector2 p2(x2-0.2,y1+0.2); TVector2 p3(x1+0.2,y2-0.2); TVector2 p4(x2-0.2,y2-0.2); if(IntersectsPaves(paves, p1,p2,p3,p4)) return; TPave* p = new TPave(x1,y1,x2,y2); p->SetBorderSize(1); p->SetFillColor(iColor); p->Draw(); paves.push_back(p); } // ------------------------------------------------------------------------- // ----- IntersectsFifty method --------------------------------------- Bool_t CbmMuchSegmentation::IntersectsFifty(Double_t iRadius, Double_t x1, Double_t y1, Double_t x2, Double_t y2){ Bool_t ul = kFALSE; Bool_t ur = kFALSE; Bool_t bl = kFALSE; Bool_t br = kFALSE; Int_t i = 0; Double_t Scard = (x2-x1)*(y2-y1); Double_t a,b,A,B,C,S; if(sqrt(x1*x1 + y1*y1) < iRadius) { bl = kTRUE; i++; } if(sqrt(x1*x1 + y2*y2) < iRadius){ ul = kTRUE; i++; } if(sqrt(x2*x2 + y2*y2) < iRadius) { ur = kTRUE; i++; } if(sqrt(x2*x2 + y1*y1) < iRadius) { br = kTRUE; i++; } if (i==3 || i== 4) return kTRUE; else if(i==0 || i==1) return kFALSE; else if(i==2){ if(ur && br){ B = y2; C = y1; A = x2; } else if(ul && ur){ B = x2; C = x1; A = y2; } else if(bl && ul){ B = y2; C = y1; A = x1; } else if(bl && br){ B = x2; C = x1; A = y1; } a = sqrt(iRadius*iRadius - B*B) - fabs(A); b = sqrt(iRadius*iRadius - C*C) - fabs(A); S = (a+b)/2.*(B-C); if(S/Scard > 0.5) return kTRUE; } return kFALSE; } // ------------------------------------------------------------------------- // ------ IntersectsPaves method --------------------------------------- Bool_t CbmMuchSegmentation::IntersectsPaves(vector paves, TVector2 p1, TVector2 p2, TVector2 p3, TVector2 p4){ for(int l = 0;l<(int)paves.size();l++){ if(IntersectsPave(paves.at(l),p1,p2,p3,p4)){ return kTRUE; break; } } return kFALSE; } // ------------------------------------------------------------------------- // ------ IntersectsPave method ---------------------------------------- Bool_t CbmMuchSegmentation::IntersectsPave(TPave* pave, TVector2 p1, TVector2 p2, TVector2 p3, TVector2 p4){ Double_t xPave1 = pave->GetX1(); Double_t yPave1 = pave->GetY1(); Double_t xPave2 = pave->GetX2(); Double_t yPave2 = pave->GetY2(); Double_t x1 = p1.Px(); Double_t x2 = p2.Px(); Double_t x3 = p3.Px(); Double_t x4 = p4.Px(); Double_t y1 = p1.Py(); Double_t y2 = p2.Py(); Double_t y3 = p3.Py(); Double_t y4 = p4.Py(); if((x1xPave1 && y1 < yPave2 && y1 > yPave1) || (x2xPave1 && y2 < yPave2 && y2 > yPave1) || (x3xPave1 && y3 < yPave2 && y3 > yPave1) || (x4xPave1 && y4 < yPave2 && y4 > yPave1)) return kTRUE; return kFALSE; } // ------------------------------------------------------------------------- // ------ IntersectsRegion method -------------------------------------- Bool_t CbmMuchSegmentation::IntersectsRegion(Double_t iRadius, Double_t x1, Double_t y1, Double_t x2, Double_t y2){ Bool_t r1 = kFALSE; Bool_t r2 = kFALSE; Bool_t r3 = kFALSE; Bool_t r4 = kFALSE; if(TMath::Sqrt(x1*x1 + y1*y1) < iRadius) { r1 = kTRUE; } if(TMath::Sqrt(x1*x1 + y2*y2) < iRadius){ r2 = kTRUE; } if(TMath::Sqrt(x2*x2 + y2*y2) < iRadius) { r3 = kTRUE; } if(TMath::Sqrt(x2*x2 + y1*y1) < iRadius) { r4 = kTRUE; } return (r1 || r2 || r3 || r4); } // ------------------------------------------------------------------------- // ------ CreateAsciiInputPads method ---------------------------------- void CbmMuchSegmentation::CreateAsciiInputPads(int iLayer, int iType, vector paves){ ofstream digiFile(fDigiFileName, ios::app); Double_t minLx = fMinSectorWidth[iLayer]; Double_t minLy = fMinSectorLength[iLayer]; Double_t minDx = fMinPadWidth[iLayer]; Double_t minDy = fMinPadLength[iLayer]; Double_t minSecArea = minLx*minLy; Double_t angle = fAngle[iLayer]; for (int j = 0; j<3;j++){ digiFile << (iLayer)*3 + j + 1 << "\t" << angle*(j-1) << "\t" << paves.size() << endl; for(int i=0; i<(int)paves.size();i++){ TPave* pave = paves.at(i); Double_t lx = pave->GetX2() - pave->GetX1(); Double_t ly = pave->GetY2() - pave->GetY1(); Double_t x0 = pave->GetX1() + lx/2.; Double_t y0 = pave->GetY1() + ly/2.; Double_t angle = 0.; Double_t secArea = lx*ly; Int_t ratio = (int)((secArea + 1e-7)/minSecArea); Double_t dx; Double_t dy; // number of the region for the sector Int_t iRegion = (Int_t)(log(ratio)/0.693147) + 1; Int_t k = (iRegion-1)/2; Int_t l = iRegion/2; // Calculate pad sizes if(fabs(minLx-minLy)<1e-7){ dx = pow(2.,k)*minDx; dy = pow(2.,l)*minDy; } else { dx = pow(2.,l)*minDx; dy = pow(2.,k)*minDy; if(minLx > minLy){ Double_t temp = dx; dx = dy; dy = temp; } } digiFile << i+1 << "\t" << iType << "\t" << x0 << "\t" << y0 << "\t" << angle << "\t" << lx << "\t" << ly << "\t" << dx << "\t" << dy << endl; } } digiFile.close(); } // ------------------------------------------------------------------------- // ------ CreateAsciiInputStrips method -------------------------------- // void CbmMuchSegmentation::CreateAsciiInputStrips(int iLayer, // int iType, vector paves, // double minSecLx, double minSecLy, // double minPadLx, double minPadLy){ // ofstream digiFile(fDigiFileName, ios::app); // double minSecArea = minSecLx*minSecLy; // for (int j = 0; j<3;j++){ // digiFile << (iLayer)*3 + j + 1 << "\t" << j*10. << "\t" << paves.size() << endl; // for(int i=0; i<(int)paves.size();i++){ // TPave* pave = paves.at(i); // Double_t width = pave->GetX2() - pave->GetX1(); // Double_t height = pave->GetY2() - pave->GetY1(); // Double_t x0 = pave->GetX1() + width/2.; // Double_t y0 = pave->GetY1() + height/2.; // Double_t lx = width; // Double_t ly = height; // Double_t angle = 0.; // double secArea = lx*ly; // int ratio = (int)((secArea + 0.001)/minSecArea); // Double_t dx = minPadLx; // Double_t dy = minPadLy*ratio; // digiFile << i+1 << "\t" << iType << "\t" << x0 << "\t" << y0 << "\t" << angle << "\t" // << lx << "\t" << ly << "\t" << dx << "\t" << dy << endl; // } // } // digiFile.close(); // } // ------------------------------------------------------------------------- ClassImp(CbmMuchSegmentation)