20 #include <FairRuntimeDb.h>
27 #include <TMathBase.h>
28 #include <TObjArray.h>
46 , fInputFileName((char*)
"much.digi.root")
65 , fInputFileName(inputFileName)
66 , fDigiFileName(digiFileName)
84 Fatal(
"SetNRegions",
"iStation is out of range.");
86 fRadii[iStation].resize(nRegions);
87 fSecLx[iStation].resize(nRegions);
88 fSecLy[iStation].resize(nRegions);
89 fNCols[iStation].resize(nRegions);
90 fNRows[iStation].resize(nRegions);
92 if (
fDebug) { printf(
"Station %i has %i regions\n", iStation + 1, nRegions); }
95 Int_t n = Int_t(TMath::Log2(
fNChannels[iStation]) + 1e-2);
96 Int_t nChans = Int_t(TMath::Power(2, n) + 1e-2);
99 "Number of channels should be equal to two with integer power.");
100 Int_t nPower = n / 2;
101 for (Int_t iRegion = 0; iRegion <
fNRegions[iStation]; ++iRegion) {
102 fNCols[iStation].at(iRegion) = (Int_t) TMath::Power(2, nPower);
103 fNRows[iStation].at(iRegion) = n % 2 != 0
104 ? (Int_t) TMath::Power(2, nPower + 1)
105 :
fNCols[iStation].at(iRegion);
108 printf(
"Region %i has %i columns and %i rows per sector\n",
110 fNCols[iStation].at(iRegion),
111 fNRows[iStation].at(iRegion));
120 Fatal(
"SetNChannels",
"iStation is out of range.");
125 printf(
"Station %i has %i channels per sector\n", iStation + 1, nChannels);
135 Fatal(
"SetRegionRadius",
"iStation is out of range.");
136 if (iRegion < 0 || iRegion >=
fNRegions[iStation])
137 Fatal(
"SetRegionRadius",
"iRegion is out of range.");
138 fRadii[iStation].at(iRegion) = radius;
140 printf(
"Radius of the Region %i of station %i is %4.2f cm\n",
143 fRadii[iStation].at(iRegion));
154 Fatal(
"SetSigma",
"iStation is out of range.");
155 if (iRegion < 0 || iRegion >=
fNRegions[iStation])
156 Fatal(
"SetSigma",
"iRegion is out of range.");
158 Double_t secLx =
fSecLx[iStation].at(iRegion) =
159 fNCols[iStation].at(iRegion) * TMath::Sqrt(12.) * sigmaX;
160 Double_t secLy =
fSecLy[iStation].at(iRegion) =
161 fNRows[iStation].at(iRegion) * TMath::Sqrt(12.) * sigmaY;
162 if (TMath::Abs(secLy - secLx) < 1e-5)
return;
163 if (TMath::Abs(secLy / secLx - 2) > 1e-5) {
164 if (secLy > 2 * secLx) {
165 fNCols[iStation].at(iRegion) *= 2;
166 fNRows[iStation].at(iRegion) /= 2;
168 fNCols[iStation].at(iRegion) /= 2;
169 fNRows[iStation].at(iRegion) *= 2;
171 SetSigma(iStation, iRegion, sigmaX, sigmaY);
182 Fatal(
"SetPadSize",
"iStation is out of range.");
183 if (iRegion < 0 || iRegion >=
fNRegions[iStation])
184 Fatal(
"SetPadSize",
"iRegion is out of range.");
186 Double_t secLx =
fSecLx[iStation].at(iRegion) =
187 fNCols[iStation].at(iRegion) * padLx;
188 Double_t secLy =
fSecLy[iStation].at(iRegion) =
189 fNRows[iStation].at(iRegion) * padLy;
190 if (TMath::Abs(secLy - secLx) < 1e-5)
return;
191 if (TMath::Abs(secLy / secLx - 2) > 1e-5) {
192 if (secLy > 2 * secLx) {
193 fNCols[iStation].at(iRegion) *= 2;
194 fNRows[iStation].at(iRegion) /= 2;
196 fNCols[iStation].at(iRegion) /= 2;
197 fNRows[iStation].at(iRegion) *= 2;
207 FairRuntimeDb* db = FairRuntimeDb::instance();
208 if (!db) Fatal(
"Init",
"No runtime database");
215 printf(
"\n============================= Inputs segmentation parameters "
216 "================================\n");
218 printf(
"\n==================================================================="
219 "============================\n");
224 if (!
fStations) Fatal(
"Init",
"No input array of MUCH stations.");
226 Fatal(
"Init",
"Incorrect number of stations.");
229 for (Int_t iStation = 0; iStation <
fNStations; ++iStation) {
230 printf(
"Station %i\n", iStation + 1);
231 for (Int_t iRegion = 0; iRegion <
fNRegions[iStation]; ++iRegion) {
232 printf(
"Region %i: fSecLx = %f fSecLy = %f\n",
234 fSecLx[iStation].at(iRegion),
235 fSecLy[iStation].at(iRegion));
236 printf(
"fNCols = %i fNRows = %i\n",
237 fNCols[iStation].at(iRegion),
238 fNRows[iStation].at(iRegion));
250 for (Int_t iStation = 0; iStation <
fStations->GetEntries(); ++iStation) {
254 for (Int_t iLayer = 0; iLayer < nLayers; ++iLayer) {
256 if (!layer) Fatal(
"SegmentMuch",
"Incomplete layers array.");
261 printf(
"Station %i segmented\n", iStation + 1);
265 TFile* oldfile = gFile;
282 if (!layerSide) Fatal(
"SegmentLayerSide",
"Incomplete layer sides array.");
284 for (Int_t iModule = 0; iModule < nModules; iModule++) {
298 Bool_t useModuleDesign) {
307 TVector3 size = module->
GetSize();
308 Double_t modLx = size.X();
309 Double_t modLy = size.Y();
310 Double_t modLz = size.Z();
312 Double_t modX = position.X();
313 Double_t modY = position.Y();
314 Double_t modZ = position.Z();
316 Int_t nCols = Int_t(modLx / secMaxLx);
317 Int_t nRows = Int_t(modLy / secMaxLy);
318 Int_t nX = modX < 0 ? -1 : 1;
319 Int_t nY = modY < 0 ? -1 : 1;
322 TVector3 secSize, secPosition;
324 for (Int_t iCol = 0; iCol < nCols; ++iCol) {
325 secX = useModuleDesign ? modX + nX * ((iCol + 0.5) * secMaxLx - modLx / 2.)
326 : secMaxLx * nCols / 2. - (0.5 + iCol) * secMaxLx;
327 for (Int_t iRow = 0; iRow < nRows; ++iRow) {
328 secY = useModuleDesign
329 ? modY + nY * ((iRow + 0.5) * secMaxLy - modLy / 2.)
330 : secMaxLy * nRows / 2. - (0.5 + iRow) * secMaxLy;
332 secSize.SetXYZ(secMaxLx, secMaxLy, modLz);
333 secPosition.SetXYZ(secX, secY, modZ);
339 fNCols[iStation].at(iRegion),
340 fNRows[iStation].at(iRegion)));
345 Int_t nPadRows, nPadCols;
346 Int_t n = useModuleDesign ? 1 : 2;
347 Double_t ly = useModuleDesign ? modLy - secMaxLy * nRows
348 : (modLy - secMaxLy * nRows) / 2.;
350 nPadRows = Int_t(ly / padMaxLy);
351 for (Int_t
i = 0;
i < n; ++
i) {
352 secY = useModuleDesign ? modY + nY * (modLy / 2. - ly / 2.)
353 : TMath::Power(-1,
i) * (modLy / 2. - ly / 2.);
354 for (Int_t iCol = 0; iCol < nCols; ++iCol) {
355 secX = useModuleDesign
356 ? modX + nX * ((iCol + 0.5) * secMaxLx - modLx / 2.)
357 : secMaxLx * nCols / 2. - (0.5 + iCol) * secMaxLx;
359 secSize.SetXYZ(secMaxLx, ly, modLz);
360 secPosition.SetXYZ(secX, secY, modZ);
366 fNCols[iStation].at(iRegion),
372 Double_t lx = useModuleDesign ? modLx - secMaxLx * nCols
373 : (modLx - secMaxLx * nCols) / 2.;
375 nPadCols = (Int_t)(lx / padMaxLx);
376 for (Int_t
i = 0;
i < n; ++
i) {
377 secX = useModuleDesign ? modX + nX * (modLx / 2. - lx / 2.)
378 : TMath::Power(-1,
i) * (modLx / 2. - lx / 2.);
379 for (Int_t iRow = 0; iRow < nRows; ++iRow) {
380 secY = useModuleDesign
381 ? modY + nY * ((iRow + 0.5) * secMaxLy - modLy / 2.)
382 : secMaxLy * nRows / 2. - (0.5 + iRow) * secMaxLy;
384 secSize.SetXYZ(lx, secMaxLy, modLz);
385 secPosition.SetXYZ(secX, secY, modZ);
393 fNRows[iStation].at(iRegion)));
398 if (lx > padMaxLx && ly > padMaxLy) {
399 nPadCols = (Int_t)(lx / padMaxLx);
400 nPadRows = (Int_t)(ly / padMaxLy);
401 secX = modX + nX * (modLx / 2. - lx / 2.);
402 secY = modY + nY * (modLy / 2. - ly / 2.);
404 secSize.SetXYZ(lx, ly, modLz);
405 secPosition.SetXYZ(secX, secY, modZ);
409 detectorId, iSector, secPosition, secSize, nPadCols, nPadRows));
417 TVector3 secSize = sector->
GetSize();
422 Double_t secLx = secSize.X();
423 Double_t secLy = secSize.Y();
424 Double_t secLz = secSize.Z();
425 Double_t padLx = sector->
GetPadDx();
426 Double_t padLy = sector->
GetPadDy();
427 Double_t secX = secPosition.X();
428 Double_t secY = secPosition.Y();
429 Double_t secZ = secPosition.Z();
433 Int_t nX = secX < 0 ? -1 : 1;
434 Int_t nY = secY < 0 ? -1 : 1;
440 if (!resultX && !resultY) {
444 Double_t rMax = station->
GetRmax();
448 nCols = isIncomplete ? nCols :
fNCols[iStation].at(iRegion);
449 nRows = isIncomplete ? nRows :
fNRows[iStation].at(iRegion);
451 detectorId, iSector, secPosition, secSize, nCols, nRows));
459 Double_t pLx = nC == 0 ? padLx : nC *
GetPadMaxSize(module,
"Width");
460 Double_t pLy = nR == 0 ? padLy : nR *
GetPadMaxSize(module,
"Length");
461 Double_t sLx = nC == 0 ? secLx : nC *
GetSectorMaxSize(module,
"Width", iReg);
464 nCols = Int_t(sLx / pLx);
465 nRows = Int_t(sLy / pLy);
468 TVector3 position, size;
469 Double_t newSecLx = 0., newSecLy = 0., newSecX = 0., newSecY = 0.;
470 for (Int_t
i = 0;
i < 2; ++
i) {
472 resultX ?
i * (secLx - newSecLx) + (1 -
i) * pLx / 2. * nCols : secLx;
474 resultY ?
i * (secLy - newSecLy) + (1 -
i) * pLy / 2. * nRows : secLy;
476 ? secX - TMath::Power(-1,
i) * nX * (secLx / 2. - newSecLx / 2.)
479 ? secY - TMath::Power(-1,
i) * nY * (secLy / 2. - newSecLy / 2.)
482 Double_t newPadLx = resultX ? pLx / 2. : padLx;
483 Double_t newPadLy = resultY ? pLy / 2. : padLy;
484 nCols = Int_t(newSecLx / newPadLx);
485 nRows = Int_t(newSecLy / newPadLy);
487 position.SetXYZ(newSecX, newSecY, secZ);
488 size.SetXYZ(newSecLx, newSecLy, secLz);
492 detectorId, iSector, position, size, nCols, nRows));
500 if (radius < 0)
return 0;
502 Int_t intersects = 0;
504 Double_t modLx = module->
GetSize()[0];
505 Double_t modLy = module->
GetSize()[1];
509 Double_t ulR = TMath::Sqrt((modX - modLx / 2.) * (modX - modLx / 2.)
510 + (modY + modLy / 2.) * (modY + modLy / 2.));
511 Double_t urR = TMath::Sqrt((modX + modLx / 2.) * (modX + modLx / 2.)
512 + (modY + modLy / 2.) * (modY + modLy / 2.));
513 Double_t blR = TMath::Sqrt((modX - modLx / 2.) * (modX - modLx / 2.)
514 + (modY - modLy / 2.) * (modY - modLy / 2.));
515 Double_t brR = TMath::Sqrt((modX + modLx / 2.) * (modX + modLx / 2.)
516 + (modY - modLy / 2.) * (modY - modLy / 2.));
518 if (ulR < radius) intersects++;
519 if (urR < radius) intersects++;
520 if (blR < radius) intersects++;
521 if (brR < radius) intersects++;
523 if (intersects == 4)
return 2;
534 if (radius < 0)
return 0;
536 Int_t intersects = 0;
538 Double_t secLx = sector->
GetSize()[0];
539 Double_t secLy = sector->
GetSize()[1];
543 Double_t ulR = TMath::Sqrt((secX - secLx / 2.) * (secX - secLx / 2.)
544 + (secY + secLy / 2.) * (secY + secLy / 2.));
545 Double_t urR = TMath::Sqrt((secX + secLx / 2.) * (secX + secLx / 2.)
546 + (secY + secLy / 2.) * (secY + secLy / 2.));
547 Double_t blR = TMath::Sqrt((secX - secLx / 2.) * (secX - secLx / 2.)
548 + (secY - secLy / 2.) * (secY - secLy / 2.));
549 Double_t brR = TMath::Sqrt((secX + secLx / 2.) * (secX + secLx / 2.)
550 + (secY - secLy / 2.) * (secY - secLy / 2.));
552 if (ulR < radius) intersects++;
553 if (urR < radius) intersects++;
554 if (blR < radius) intersects++;
555 if (brR < radius) intersects++;
557 if (intersects == 4)
return 2;
567 const TString direction,
569 Double_t secLx = sector->
GetSize()[0];
570 Double_t secLy = sector->
GetSize()[1];
571 Double_t secArea = secLx * secLy;
572 Double_t secL = direction ==
"X" ? secLx : secLy;
579 Double_t secRegL = direction ==
"X" ?
fSecLx[iStation].at(iRegion)
580 :
fSecLy[iStation].at(iRegion);
581 Double_t secRegArea =
582 fSecLx[iStation].at(iRegion) *
fSecLy[iStation].at(iRegion);
584 if (secArea > secRegArea) {
586 if (secLy > secLx && direction ==
"X"
590 if (secLy <= secLx && direction ==
"Y")
return false;
593 if (secL > secRegL)
return true;
602 Double_t secLx = sector->
GetSize()[0];
603 Double_t secLy = sector->
GetSize()[1];
604 Double_t secArea = secLx * secLy;
605 Double_t sX = TMath::Abs(sector->
GetPosition()[0]) - secLx / 2.;
606 Double_t sY = TMath::Abs(sector->
GetPosition()[1]) - secLy / 2.;
607 Double_t secRad = TMath::Sqrt(sX * sX + sY * sY);
611 for (Int_t iReg = 0; iReg <
fNRegions[iStation]; ++iReg) {
612 Double_t secRegArea =
fSecLx[iStation].at(iReg) *
fSecLy[iStation].at(iReg);
613 Double_t regionRad =
fRadii[iStation].at(iReg);
614 if (secRad > regionRad)
continue;
618 Double_t secPrevRegArea =
619 fSecLx[iStation].at(iReg - 1) *
fSecLy[iStation].at(iReg - 1);
620 if (secArea < secRegArea && secArea >= secPrevRegArea) iRegion--;
635 for (iRegion = 0; iRegion < nRegions; ++iRegion) {
636 Double_t rad =
fRadii[iStation].at(iRegion);
639 return side ==
"Width" ?
fSecLx[iStation].at(iRegion)
640 :
fSecLy[iStation].at(iRegion);
642 iRegion = nRegions - 1;
643 return side ==
"Width" ?
fSecLx[iStation].at(iRegion)
644 :
fSecLy[iStation].at(iRegion);
651 const TString side) {
655 return side ==
"Width" ? sectorSize /
fNCols[iStation].at(iRegion)
656 : sectorSize /
fNRows[iStation].at(iRegion);
663 Bool_t result =
false;
665 Double_t secLx = sector->
GetSize()[0];
666 Double_t secLy = sector->
GetSize()[1];
667 Double_t minL = TMath::Min(secLx, secLy);
668 Double_t maxL = TMath::Max(secLx, secLy);
669 Int_t nFrac = Int_t((maxL + 1e-5) / minL);
670 Int_t nPower = Int_t(TMath::Log2(nFrac) + 1e-2);
671 Double_t maxL1 = minL * TMath::Power(2, nPower);
673 if (TMath::Abs(maxL - maxL1) > 1e-5
683 Int_t nTotSectors = 0;
684 Int_t nTotChannels = 0;
686 Int_t nTotStraws = 0;
687 printf(
"====================================================================="
688 "============================\n");
689 for (Int_t iStation = 0; iStation <
fStations->GetEntries(); ++iStation) {
703 if (!station)
continue;
704 for (Int_t iLayer = 0; iLayer < station->
GetNLayers(); ++iLayer) {
706 if (!layer)
continue;
707 for (Int_t iSide = 0; iSide < 2; ++iSide) {
710 for (Int_t iModule = 0; iModule < side->
GetNModules(); ++iModule) {
717 if (!module)
continue;
720 for (Int_t iSector = 0; iSector < module->
GetNSectors();
724 if (!sector)
continue;
725 Double_t padLx = sector->
GetPadDx();
726 Double_t padLy = sector->
GetPadDy();
727 if (padLx > padMaxLx) {
729 secMaxLx = sector->
GetPadNx() * padLx;
731 if (padLx < padMinLx) {
733 secMinLx = sector->
GetPadNx() * padLx;
735 if (padLy > padMaxLy) {
737 secMaxLy = sector->
GetPadNy() * padLy;
739 if (padLy < padMinLy) {
741 secMinLy = sector->
GetPadNy() * padLy;
754 printf(
"Station %i:\n", iStation + 1);
755 printf(
" GEM modules: %i\n", nGems);
757 printf(
" Sectors: %i, Min.Sector size:%3.2fx%3.2f, Max.Sector "
758 "size:%3.2fx%3.2f\n",
764 for (Int_t iReg = 0; iReg <
fNRegions.at(iStation); ++iReg) {
765 printf(
"Region %i: size %fx%f\n",
767 fSecLx.at(iStation).at(iReg),
768 fSecLy.at(iStation).at(iReg));
771 " Pads: %i, Min.Pad size:%3.2fx%3.2f, Max.Pad size:%3.2fx%3.2f\n",
778 printf(
" Straw modules: %i\n", nStraws);
779 nTotSectors += nSectors;
780 nTotChannels += nChannels;
782 nTotStraws += nStraws;
784 printf(
"---------------------------------------------------------------------"
785 "----------------------------\n");
786 printf(
" Summary: \n GEM modules: %i\n Sectors: %i, Pads: %i\n "
787 "Straw modules: %i\n",
792 printf(
"====================================================================="
793 "============================\n");
801 for (iChar = length - 1; iChar >= 0; --iChar) {
805 txtfile[iChar + 1] =
'\0';
806 strcat(txtfile,
"txt");
809 outfile = fopen(txtfile,
"w");
818 for (Int_t iStation = 0; iStation <
fStations->GetEntriesFast(); ++iStation) {
820 "=================================================================="
822 fprintf(outfile,
"Station %i\n", iStation + 1);
824 "Sector size, cm Sector position, cm Number of pads Side "
827 "------------------------------------------------------------------"
829 TCanvas* c1 =
new TCanvas(Form(
"station%i", iStation + 1),
830 Form(
"station%i", iStation + 1),
834 c1->Range(-250, -250, 250, 250);
837 for (Int_t iSide = 1; iSide >= 0; iSide--) {
839 for (Int_t iModule = 0; iModule < layerSide->
GetNModules(); ++iModule) {
845 for (Int_t iSector = 0; iSector < module->
GetNSectors(); ++iSector) {
849 Double_t secLx = sector->
GetSize()[0];
850 Double_t secLy = sector->
GetSize()[1];
862 const char* side = iSide ?
"Back" :
"Front";
864 "%-4.2fx%-10.2f %-6.2fx%-12.2f %-14i %-5s ",
878 TArc* holeArc =
new TArc(0., 0., station->
GetRmin());
881 for (Int_t iRegion = 0; iRegion <
fNRegions[iStation]; ++iRegion) {
882 TArc* arc =
new TArc(0., 0.,
fRadii[iStation].at(iRegion));
883 arc->SetLineColor(kBlack);
884 arc->SetLineWidth(2);
885 arc->SetFillStyle(0);
890 Form(
"%s/station%i.eps", gSystem->DirName(
fDigiFileName), iStation + 1));
892 Form(
"%s/station%i.png", gSystem->DirName(
fDigiFileName), iStation + 1));
900 if (!infile) { Fatal(
"ReadInputFile",
"Error: Cannot open the input file."); }
908 strs =
Split(str,
' ');
909 index = strs.size() - 1;
911 StrToNum(strs.at(index), nStations);
913 printf(
"Number of stations: \t%i",
fNStations);
917 strs =
Split(str,
' ');
918 printf(
"\nNumber of channels: ");
919 for (Int_t iStation = 0; iStation <
fNStations; ++iStation) {
922 StrToNum(strs.at(index), nChannels);
929 strs =
Split(str,
' ');
930 printf(
"\nNumber of regions: ");
931 for (Int_t iStation = 0; iStation <
fNStations; ++iStation) {
939 for (Int_t iStation = 0; iStation <
fNStations; ++iStation) {
940 vector<Double_t> padWidth(
fNRegions[iStation], 0);
941 vector<Double_t> padLength(
fNRegions[iStation], 0);
945 strs =
Split(str,
' ');
946 printf(
"\nStation %i", iStation + 1);
947 printf(
"\n Region radii [cm]: ");
948 for (Int_t iRegion = 0; iRegion <
fNRegions[iStation]; ++iRegion) {
949 index = strs.size() -
fNRegions[iStation] + iRegion;
953 printf(
"\t%4.2f",
fRadii[iStation].at(iRegion));
958 strs =
Split(str,
' ');
959 printf(
"\n Pad width [cm]: ");
960 for (Int_t iRegion = 0; iRegion <
fNRegions[iStation]; ++iRegion) {
961 index = strs.size() -
fNRegions[iStation] + iRegion;
962 StrToNum(strs.at(index), padWidth.at(iRegion));
963 printf(
"\t%4.2f", padWidth.at(iRegion));
968 strs =
Split(str,
' ');
969 printf(
"\n Pad length [cm]: ");
970 for (Int_t iRegion = 0; iRegion <
fNRegions[iStation]; ++iRegion) {
971 index = strs.size() -
fNRegions[iStation] + iRegion;
972 StrToNum(strs.at(index), padLength.at(iRegion));
973 printf(
"\t%4.2f", padLength.at(iRegion));
976 for (Int_t iRegion = 0; iRegion <
fNRegions[iStation]; ++iRegion)
978 iStation, iRegion, padWidth.at(iRegion), padLength.at(iRegion));