/** CbmMuchSegmentation.cxx *@author Mikhail Ryzhinskiy *@since 20.06.07 *@version 1.0 ** **@version 1.1 **@ change made by Dipanwita Dutta ** to implement "Flexible Segmentation Scheme" ** ** class for making parameter file for MUCH digitizer ** **/ #include "CbmGeoMuchPar.h" #include "CbmMuchSegmentation.h" #include "CbmRunAna.h" #include "CbmRuntimeDb.h" #include "CbmRootManager.h" #include "CbmMuchPoint.h" #include "TCanvas.h" #include "TStyle.h" #include "TString.h" #include "TArrow.h" #include "TEllipse.h" #include "TMath.h" #include "TObjArray.h" #include "TClonesArray.h" #include "TArrayD.h" #include "TH1.h" #include #include #include #include #include #include using std::cout; using std::endl; using std::ios; using std::vector; using std::sqrt; using std::pow; using std::fabs; using std::log; using std::map; using std::pair; // ----- Default constructor ------------------------------------------ CbmMuchSegmentation::CbmMuchSegmentation(){ } // ------------------------------------------------------------------------- // ----- Default constructor ------------------------------------------- CbmMuchSegmentation::CbmMuchSegmentation(char* digiFileName){ fDigiFileName = digiFileName; fNStations = 0; Double_t hdArray[] = {0.4, 0.2, 0.1, 0.05, 0.025, 0.01, 0.005, 0.0025, 0.001}; Double_t hdSigmaX[] = {400, 800, 800, 1600, 1600, 3200, 3200, 6400, 6400}; Double_t hdSigmaY[] = {800, 800, 1600, 1600, 3200, 3200, 6400, 6400, 12800}; fHitDensities.assign(hdArray, hdArray+sizeof(hdArray)/sizeof(Double_t)); // Hit density boundaries fSigmasX.assign(hdSigmaX, hdSigmaX+sizeof(hdSigmaX)/sizeof(Double_t)); fSigmasY.assign(hdSigmaY, hdSigmaY+sizeof(hdSigmaY)/sizeof(Double_t)); Double_t padW[] = {0.138564, 0.277128, 0.277128, 0.554256, 0.554256, 1.108512, 1.108512, 2.217024, 2.217024}; Double_t padL[] = {0.277128, 0.277128, 0.554256, 0.554256, 1.108512, 1.108512, 2.217024, 2.217024, 4.434048}; fPadW.assign(padW, padW+sizeof(padW)/sizeof(Double_t)); // Define padW fPadL.assign(padL, padL+sizeof(padL)/sizeof(Double_t)); // Define padL } // ----- Destructor ---------------------------------------------------- CbmMuchSegmentation::~CbmMuchSegmentation() { } // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- // ----- Private method SetParContainers -------------------------------- void CbmMuchSegmentation::SetParContainers() { // Get run and runtime database CbmRunAna* run = CbmRunAna::Instance(); if ( ! run ) Fatal("SetParContainers", "No analysis run"); CbmRuntimeDb* db = run->GetRuntimeDb(); if ( ! db ) Fatal("SetParContainers", "No runtime database"); // Get MUCH geometry parameter container fGeoPar = (CbmGeoMuchPar*) db->getContainer("CbmGeoMuchPar"); } // ------------------------------------------------------------------------- // ----- Private method Init -------------------------------------------- InitStatus CbmMuchSegmentation::Init() { // Get arrays of sensitive and passive nodes cout << "Digi file: " << fDigiFileName << endl; // Option for Diff. Seg. Scheme: fOption =0 for 5% Occ; // =1 for Flexible Seg. Scheme // =2 for Flexible Seg. Scheme with sector size=pad size if(fOption==2){ TObject::Fatal("CbmMuchSegmentation::SetSegOption","option= 2 is not supported yet"); } TObjArray* sensNodes = fGeoPar->GetGeoSensitiveNodes(); TObjArray* passNodes = fGeoPar->GetGeoPassiveNodes(); Int_t nSensNodes = sensNodes->GetEntries(); Int_t nPassNodes = passNodes->GetEntries(); // Sort geo nodes by z coordinate map > geoNodesMap; for(Int_t iPassNode = 0; iPassNode < nPassNodes; iPassNode++){ CbmGeoNode* node = (CbmGeoNode*)(passNodes->At(iPassNode)); // Search for mother volume CbmGeoNode* motherVolume = (CbmGeoNode*)(passNodes->FindObject(node->getMother().Data())); if(!motherVolume) continue; Double_t z = node->getParameters()->At(3); if(geoNodesMap.find(z) == geoNodesMap.end()){ pair p(kPassive, node); geoNodesMap[z] = p; } } for(Int_t iSensNode = 0; iSensNode < nSensNodes; iSensNode++){ CbmGeoNode* node = (CbmGeoNode*)(sensNodes->At(iSensNode)); Double_t z = node->getParameters()->At(3); if(geoNodesMap.find(z) == geoNodesMap.end()){ pair p(kSensitive, node); geoNodesMap[z] = p; } } // Calculate region radia FillRadia(geoNodesMap); // Fill vectors with region radia Int_t incAbsorbers = 0; // number of absorbers Int_t incStations = 0; // number of layers for(map >::iterator it=geoNodesMap.begin(); it!=geoNodesMap.end(); it++){ pair p = (*it).second; GeoNodeType nodeType = p.first; CbmGeoNode* node = p.second; if(nodeType == kPassive){ incAbsorbers++; continue; } else if(nodeType == kSensitive){ incStations++; TArrayD* params = node->getParameters(); vector regionRadia; Double_t rInt = params->At(7); Double_t rExt = params->At(8); vector radia; vector regions; Double_t temp=rInt; frInt.push_back(temp); // Fill min resolution vectors with default values if needed regions = fRadiaInt[incAbsorbers-1]; if(incStations > fMinSigmaX.size()) SetNStations(incStations); if(fMinSigmaX[incStations-1] < 50.) SetMinSigmaX(incStations, fSigmasX[fHDIndices[incAbsorbers - 1]]); if(fMinSigmaY[incStations-1] < 50.) SetMinSigmaY(incStations, fSigmasY[fHDIndices[incAbsorbers - 1]]); // Fill radia vectors for each station if(fOption == 1 ){ if(incStations <= 6)rInt=rInt-5; if(incStations > 6)rInt=rInt-10; if(incStations > 9)rInt=rInt-18; } radia.push_back(rInt); for(vector::iterator iter=regions.begin(); iter!=regions.end(); iter++){ Double_t r = (*iter); if(rInt < r && r < rExt) //if(TMath::Abs(rInt-r) > 5 && TMath::Abs(rExt-r) > 5) radia.push_back(r); if(TMath::Abs(rExt-r) > 7) radia.push_back(r); } radia.push_back(rExt); fRadia.push_back(radia); } } // cout << "Number of absorbers = " << incAbsorbers << endl; // cout << "fRadiaInt.size() = " << fRadiaInt.size() << endl; // cout << "fHDIndices.size() = " << fHDIndices.size() << endl; // cout << "final incStations = " << incStations << endl; SetNStations(incStations); // Make segmentation for each station SegmentMuch(); return kSUCCESS; } // ------------------------------------------------------------------------- // ----- Private method FillRadia --------------------------------------- void CbmMuchSegmentation::FillRadia(map > geoNodesMap){ gStyle->SetOptStat(0); Bool_t afterAbsorber = kFALSE; // auxilary flag showing whether a station comes after an absorber vector > stationBorders; // borders of a station coming after an absorber // Fill stationBorders vector Int_t absorberInc = 0; vector hitDensityHist; Int_t binSize = 2; for(map >::iterator it=geoNodesMap.begin(); it!=geoNodesMap.end(); it++){ pair p = (*it).second; GeoNodeType nodeType = p.first; CbmGeoNode* node = p.second; CbmGeoTransform* transform = node->getLabTransform(); CbmGeoVector translation = transform->getTranslation(); if(nodeType == kPassive){ absorberInc++; afterAbsorber = kTRUE; continue; } else if(nodeType == kSensitive){ TArrayD* params = node->getParameters(); Double_t z1 = translation.Z() + params->At(3); Double_t z2 = translation.Z() + params->At(6); Double_t rExt = params->At(8); if(afterAbsorber){ pair zPair(z1, z2); stationBorders.push_back(zPair); // Initialize histograms char title[256]; char name[256]; sprintf(title, "After %d absorber",absorberInc); sprintf(name, "Absorber%d", absorberInc); TH1D* hist = new TH1D(name, title, 100, 0, 200); hist->GetXaxis()->SetTitle("r, cm"); hist->GetYaxis()->SetTitle("hits/(event#timescm^{2})"); hitDensityHist.push_back(hist); afterAbsorber = kFALSE; } } } // Get MC points array CbmRootManager* ioman = CbmRootManager::Instance(); if ( ! ioman ) Fatal("Init", "No CbmRootManager"); TClonesArray* mcPoints = (TClonesArray*) ioman->GetObject("MuchPoint"); // Loop over all events Int_t nEvents = ioman->GetInTree()->GetEntries(); for(Int_t iEvent = 0; iEvent < nEvents; iEvent++){ ioman->ReadEvent(iEvent); for(Int_t iPoint = 0; iPoint < mcPoints->GetEntriesFast(); iPoint++){ CbmMuchPoint* point = (CbmMuchPoint*)mcPoints->At(iPoint); TVector3 position; point->Position(position); for(Int_t l=0; l<100; l++){ if(position.Pt() >= binSize*(l-1) && position.Pt() < binSize*l){ Double_t s = TMath::Pi()*binSize*binSize*(2*l - 1); Int_t inc = 0; for(vector >::iterator iter = stationBorders.begin(); iter!=stationBorders.end(); iter++){ pair zPair = *iter; Double_t z1 = zPair.first - 0.1; Double_t z2 = zPair.second + 0.1; Double_t zPoint = point->GetZIn(); if(zPoint > z1 && zPoint < z2) { hitDensityHist[inc]->Fill(position.Pt(), 1./(nEvents*s)); break; } inc++; } } } } } // Analyze hit density histograms Int_t nGaps = hitDensityHist.size(); for(Int_t iGap = 0; iGap < nGaps; iGap++){ TH1D* h = hitDensityHist[iGap]; // Calculate internal radia CalculateInternalRadia(h,iGap); if(fOption == 0)fRadiaInt.push_back(fRad0[iGap]); if(fOption == 1 || fOption == 2)fRadiaInt.push_back(fRad1[iGap]); // Draw and print histograms TCanvas* c1 = new TCanvas("c1","c1", 10,10,500,500); c1->SetLogy(); c1->SetLeftMargin(0.12); c1->SetRightMargin(0.08); h->SetMaximum(1.1); h->SetMinimum(9e-6); h->SetLineColor(4); h->SetLineWidth(5); h->GetYaxis()->SetTitleOffset(1.27); h->Draw(); char name[256]; sprintf(name, "absorber%d.eps", iGap+1); c1->Print(name); } } // ------------------------------------------------------------------------- void CbmMuchSegmentation::SetRadius(int i, int dim_rad, int dim_reg, Double_t *Rad, Int_t *Reg){ vector Radia; // List of ring radia vector Region; //List of ring regioins Radia.assign (Rad, Rad+dim_rad); Region.assign (Reg, Reg+dim_reg); /* cout<<"station no.= "< radiaInt; // List of ring radia Int_t maxNRegions = fHitDensities.size(); // Maximal number of ring regions Double_t maxHD = fHitDensities[0]; // Hit density corresponding to minimal allowed pad size Double_t minHD = fHitDensities[maxNRegions-1]; // Hit density corresponding to maximal allowed pad size Int_t maxBin = hist->GetMaximumBin(); Int_t nBins = hist->GetNbinsX(); Double_t maxBinHD = hist->GetBinContent(maxBin); Double_t hd = 0; Double_t rad = 0; Int_t hdIndex = -1; for(Int_t iHD = 0; iHD < maxNRegions; iHD++){ Double_t hdBorder1 = fHitDensities[iHD]; Double_t hdBorder2 = iHD + 1 < maxNRegions ? fHitDensities[iHD+1] : 0; for(Int_t iBin = maxBin; iBin < nBins; iBin++){ hd = hist->GetBinContent(iBin); if(hd < minHD) break; if(hd > hdBorder1) continue; else{ maxBin = iBin+1 < nBins ? iBin+1 : iBin; if(hd < hdBorder2) break; if(iBin*2 - rad < 7) continue; if(hdIndex < 0) { fHDIndices.push_back(hdIndex = iHD); } rad = iBin*2; // cout << "rad = " << rad << "\thd_prev = " << hist->GetBinContent(iBin-1) // << "\thd_curr = " << hd << "\tresol = " << fSigmasX[iHD] << "x" // << fSigmasY[iHD] << endl; radiaInt.push_back(rad); break; } } if(hd < minHD) break; } if(hdIndex < 0) fHDIndices.push_back(maxNRegions-1); if(fOption == 0)fRad0.push_back(radiaInt); } // ------------------------------------------------------------------------- // ----- SetAngle method ---------------------------------------------- void CbmMuchSegmentation::SetAngle(Int_t iStation, Double_t angle){ if(iStation > fNStations){ SetNStations(iStation); } if(iStation < 1 || iStation > fNStations) { cout << "The number of the station is out of available range." << endl; return; } fAngle[iStation-1] = angle; } // ------------------------------------------------------------------------- // ----- SetMinSigmaX method ------------------------------------------ void CbmMuchSegmentation::SetMinSigmaX(Int_t iStation, Double_t sigmaX){ if(iStation > fNStations){ SetNStations(iStation); } if(iStation < 1 || iStation > fNStations) { cout << "The number of the station 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[iStation-1] = sigmaX; // Calculate corresponding pad size [cm] fMinPadWidth[iStation-1] = fMinSigmaX[iStation-1]*3.464101*1e-4; } // ------------------------------------------------------------------------- // ----- SetMinSigmaY method ------------------------------------------ void CbmMuchSegmentation::SetMinSigmaY(Int_t iStation, Double_t sigmaY){ if(iStation > fNStations){ SetNStations(iStation); } if(iStation < 1 || iStation > fNStations) { cout << "\nThe number of the station 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[iStation-1] = sigmaY; // Calculate corresponding pad size [cm] fMinPadLength[iStation-1] = fMinSigmaY[iStation-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 lx \t ly \t nCols \t nRows \n" << "#################################################################\n" << "[CbmMuchDigiPar]" << endl; digiFile.close(); // Make segmentation for each station for(Int_t iStation = 0; iStation 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[iStation] = dx; fMinPadLength[iStation] = dy; fMinSectorWidth[iStation] = lx; fMinSectorLength[iStation] = ly; if(fOption ==2){ fMinSectorWidth[iStation] = dx; fMinSectorLength[iStation] = dy; } } // ------------------------------------------------------------------------- // ----- MakeSegmentation method --------------------------------------- void CbmMuchSegmentation::MakeSegmentation(Int_t iStation){ Double_t minArea = fMinSectorWidth[0]*fMinSectorLength[0]; if(fOption==2)minArea=fPadW[0]*fPadL[0]; TString name("station"); name += iStation + 1; TCanvas* canvas = new TCanvas(name, name, 900,900); Int_t nRadia = fRadia[iStation].size(); //************** Fill regions with sectors (begin) *******************// vector paves; // objects representing sectors vector secLx(nRadia - 1); // width of sectors in each region vector secLy(nRadia - 1); // length of sectors in each region // Define sector size for each region if(fOption == 1 || fOption == 2) { vector Reg; Int_t incAbs=iStation/3; Reg=fReg[incAbs]; Int_t nReg=9; Double_t minSectorW=fMinSectorWidth[0]; Double_t minSectorL=fMinSectorLength[0]; vector secx(nReg); // width of sectors in each region vector secy(nReg); // length of sectors in each region SetSectorSizes(nReg, minSectorW, minSectorL, secx, secy); for(int i1=0; i1"); 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) **************// for(Int_t i=0; i<3 ; i++){ Int_t iSt=i+iStation; CreateDigiFile(iSt, 1, paves); // CreateDigiFile(iStation, 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, Double_t fraction){ // 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] 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); } // ------------------------------------------------------------------------- // ----- IntersectsFraction method ------------------------------------ Bool_t CbmMuchSegmentation::IntersectsFraction(Double_t iRadius, Double_t x1, Double_t y1, Double_t x2, Double_t y2, Double_t fraction){ if(fraction > 1. + 1e-7) return kFALSE; 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++; } switch(i){ case 0: return kFALSE; break; case 1: case 3: Double_t xp1, yp1, xp2, yp2; if((br && i==1) || (!br && i==3)){ xp1 = x2; yp1 = i==1 ? sqrt(iRadius*iRadius - xp1*xp1) : -sqrt(iRadius*iRadius - xp1*xp1); yp2 = y1; xp2 = i==1 ? -sqrt(iRadius*iRadius - yp2*yp2) : sqrt(iRadius*iRadius - yp2*yp2); } else if((bl && i==1) || (!bl && i==3)){ yp1= y1; xp1 = i==1 ? sqrt(iRadius*iRadius - yp1*yp1) : -sqrt(iRadius*iRadius - yp1*yp1); xp2 = x1; yp2 = i==1 ? sqrt(iRadius*iRadius - xp2*xp2) : -sqrt(iRadius*iRadius - xp2*xp2); } else if((ul && i==1) || (!ul && i==3)){ xp1 = x1; yp1 = i==1 ? -sqrt(iRadius*iRadius - xp1*xp1) : sqrt(iRadius*iRadius - xp1*xp1); yp2 = y2; xp2 = i==1 ? sqrt(iRadius*iRadius - yp2*yp2) : -sqrt(iRadius*iRadius - yp2*yp2); } else if(ur){ yp1 = y2; xp1 = i==1 ? -sqrt(iRadius*iRadius - yp1*yp1) : sqrt(iRadius*iRadius - yp1*yp1); xp2 = x2; yp2 = i==1 ? -sqrt(iRadius*iRadius - xp2*xp2) : sqrt(iRadius*iRadius - xp2*xp2); } S = 0.5*(fabs(xp1-xp2)*fabs(yp1-yp2)); if(i==1){ if(S/Scard > fraction) return kTRUE; } else if(i==3){ if((Scard - S)/S > fraction) return kTRUE; } break; case 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 > fraction) return kTRUE; break; case 4: return kTRUE; break; } 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; } // ------------------------------------------------------------------------- // ------ CreateDigiFile method ----------------------------------------- void CbmMuchSegmentation::CreateDigiFile(int iStation, int iType, vector paves){ ofstream digiFile(fDigiFileName, ios::app); Double_t minLx = fMinSectorWidth[0];//iStation]; Double_t minLy = fMinSectorLength[0];//iStation]; Double_t minDx = fMinPadWidth[0];//iStation]; Double_t minDy = fMinPadLength[0];//iStation]; Double_t minSecArea = minLx*minLy; Double_t angle = fAngle[iStation]; digiFile << iStation + 1 << "\t" << angle << "\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 secArea = lx*ly; Int_t ratio = (Int_t)((secArea + 1e-5)/minSecArea); Double_t dx; Double_t dy; // number of the region for the sector Int_t iRegion = (Int_t)(log((Double_t)ratio)/0.693147) + 1; Int_t l = (iRegion-1)/2; Int_t k = 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; } } if(fOption ==2 ) dx=lx; if(fOption ==2 ) dy=ly; Int_t nCols = (Int_t)((lx+dx/2.)/dx); Int_t nRows = (Int_t)((ly+dy/2.)/dy); // cout<<"iRegion"<