Skip to content

Commit 2b6a418

Browse files
WIP
1 parent 4344c80 commit 2b6a418

File tree

6 files changed

+188
-9
lines changed

6 files changed

+188
-9
lines changed

Detectors/FIT/FV0/base/include/FV0Base/Geometry.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class Geometry
6767
enum EGeoComponent {
6868
eScintillator,
6969
ePlastics,
70+
ePhotonFilter,
7071
ePmts,
7172
eFibers,
7273
eScrews,
@@ -278,12 +279,15 @@ class Geometry
278279
// Strings for volume names, etc.
279280
inline static const std::string sScintillatorName = "SCINT";
280281
inline static const std::string sPlasticName = "PLAST";
282+
inline static const std::string sPhotonFilterName = "PHOTONFILTER";
281283
inline static const std::string sSectorName = "SECTOR";
282284
inline static const std::string sCellName = "CELL";
283285
inline static const std::string sScintillatorSectorName = sScintillatorName + sSectorName;
284286
inline static const std::string sScintillatorCellName = sScintillatorName + sCellName;
285287
inline static const std::string sPlasticSectorName = sPlasticName + sSectorName;
286288
inline static const std::string sPlasticCellName = sPlasticName + sCellName;
289+
inline static const std::string sPhotonFilterSectorName = sPhotonFilterName + sSectorName;
290+
inline static const std::string sPhotonFilterCellName = sPhotonFilterName + sCellName;
287291
inline static const std::string sPmtName = "PMT";
288292
inline static const std::string sFiberName = "FIBER";
289293
inline static const std::string sScrewName = "SCREW";
@@ -353,7 +357,14 @@ class Geometry
353357
/// from all volumes that the rods are passing through to avoid overlaps.
354358
void initializeRodHoles();
355359

360+
/// Create cell shape expressions to be used in TGeoCompositeShape.
361+
/// This will also create and register the needed volumes and transformation used in the TGeoCompositeShape.
362+
/// \param cellType The type of the cells.
363+
/// \param zThickness The thickness of the cells.
364+
std::string createCellShapeExpressions(const std::string& cellType, const int ring, const float zThickness);
365+
356366
/// Initialize cell volumes with a specified thickness and medium.
367+
/// The celltype ('a' or 'b') can be understood fromt the CAD drawings of the detector
357368
/// \param cellType The type of the cells.
358369
/// \param zThicknes The thickness of the cells.
359370
/// \param medium The medium of the cells.
@@ -366,6 +377,9 @@ class Geometry
366377
/// Initialize plastic cell volumes for optical fiber support.
367378
void initializePlasticCells();
368379

380+
/// Initialize the photon filter between the cells. (I.e. the paint + tape.)
381+
void initializePhotonFilter();
382+
369383
/// Initialize PMTs.
370384
void initializePmts();
371385

@@ -401,6 +415,11 @@ class Geometry
401415
/// \param vFV0Left The left FV0 volume.
402416
void assemblePlasticSectors(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left) const;
403417

418+
/// Assemble the photon filters.
419+
/// \param vFV0Right The right FV0 volume.
420+
/// \param vFV0Left The left FV0 volume.
421+
void assemblePhotonFilters(TGeoVolume* vFV0RIght, TGeoVolume* vFV0Left) const;
422+
404423
/// Assemble the PMTs.
405424
/// \param vFV0Right The right FV0 volume.
406425
/// \param vFV0Left The left FV0 volume.
@@ -523,6 +542,9 @@ class Geometry
523542
std::vector<TGeoMedium*> mMediumScrewTypes; ///< Medium of the screw types
524543
std::vector<TGeoMedium*> mMediumRodTypes; ///< Medium of the rod types
525544

545+
std::vector<std::string> mACellShapeExpressions; ///< Shape expressions for the A cells
546+
std::vector<std::string> mBCellShapeExpressions; ///< Shape expressions for the B cells
547+
526548
const int mGeometryType; ///< The type of the geometry.
527549
std::map<EGeoComponent, bool> mEnabledComponents; ///< Map of the enabled state of all geometry components
528550
TGeoMatrix* mLeftTransformation; ///< Transformation for the left part of the detector

Detectors/FIT/FV0/base/src/Geometry.cxx

Lines changed: 135 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
/// \brief Implementation of FV0 geometry.
1414
///
1515
/// \author Maciej Slupecki, University of Jyvaskyla, Finland
16-
/// \author Andreas Molander, University of Helsinki, Finland
16+
/// \author Andreas Molander ([email protected])
1717

1818
#include "FV0Base/Geometry.h"
1919

@@ -94,6 +94,9 @@ bool Geometry::enableComponent(const EGeoComponent component, const bool enable)
9494

9595
void Geometry::buildGeometry() const
9696
{
97+
if (!gGeoManager) {
98+
LOG(fatal) << "FV0: No TGeoManager found!";
99+
}
97100
TGeoVolume* vALIC = gGeoManager->GetVolume("barrel");
98101
if (!vALIC) {
99102
LOG(fatal) << "FV0: Could not find the top volume";
@@ -370,6 +373,7 @@ void Geometry::initializeNonSensVols()
370373
initializeScrewHoles();
371374
initializeRodHoles();
372375
initializePlasticCells();
376+
initializePhotonFilter();
373377
initializePmts();
374378
initializeFibers();
375379
initializeScrews();
@@ -411,6 +415,118 @@ void Geometry::initializeRodHoles()
411415
new TGeoCompositeShape(sRodHolesCSName.c_str(), boolFormula.c_str());
412416
}
413417

418+
void Geometry::createCellShapeExpression(const std::string& cellType, const int ring, const float zThickness)
419+
{
420+
const float dxHoleCut = sDxHoleExtensionScintillator; // width of extension of hole 1, 2 and 7 in the "a" cell
421+
const float xHole = sDrSeparationScint + dxHoleCut; // x-placement of holes 1, 2 and 7 in the "a" cell
422+
423+
// Sector separation gap shape
424+
const std::string secSepShapeName = sDetectorName + cellType + "SectorSeparation";
425+
if (!gGeoManager->GetListOfShapes()->Contains((secSepShapeName.c_str()))) {
426+
new TGeoBBox(secSepShapeName.c_str(), mRMaxScintillator.back() + sEpsilon, sDrSeparationScint, zThickness / 2);
427+
}
428+
429+
// Sector separation gap rotations
430+
const std::string secSepRot45Name = sDetectorName + cellType + "SecSepRot45";
431+
const std::string secSepRot90Name = sDetectorName + cellType + "SecSepRot90";
432+
433+
if (!gGeoManager->GetListOfMatrices()->Contains((secSepRot45Name.c_str()))) {
434+
createAndRegisterRot(secSepRot45Name, 45, 0, 0);
435+
}
436+
437+
if (!gGeoManager->GetListOfMatrices()->Contains((secSepRot90Name.c_str()))) {
438+
createAndRegisterRot(secSepRot90Name, 90, 0, 0);
439+
}
440+
441+
// Hole shapes
442+
const std::string holeSmallName = sDetectorName + cellType + "HoleSmall";
443+
const std::string holeLargeName = sDetectorName + cellType + "HoleLarge";
444+
const std::string holeSmallCutName = sDetectorName + cellType + "HoleSmallCut";
445+
const std::string holeLargeCutName = sDetectorName + cellType + "HoleLargeCut";
446+
447+
if (!gGeoManager->GetListOfShapes()->Contains((holeSmallName.c_str()))) {
448+
new TGeoTube(holeSmallName.c_str(), 0, sDrHoleSmallScintillator, zThickness / 2);
449+
}
450+
451+
if (!gGeoManager->GetListOfShapes()->Contains((holeLargeName.c_str()))) {
452+
new TGeoTube(holeLargeName.c_str(), 0, sDrHoleLargeScintillator, zThickness / 2);
453+
}
454+
455+
if (!gGeoManager->GetListOfShapes()->Contains((holeSmallCutName.c_str()))) {
456+
new TGeoBBox(holeSmallCutName.c_str(), dxHoleCut, sDrHoleSmallScintillator, zThickness / 2);
457+
}
458+
459+
if (!gGeoManager->GetListOfShapes()->Contains((holeLargeCutName.c_str()))) {
460+
new TGeoBBox(holeLargeCutName.c_str(), dxHoleCut, sDrHoleLargeScintillator, zThickness / 2);
461+
}
462+
463+
const float rMin = mRAvgRing[ring];
464+
const float rMax = mRAvgRing[ring + 1];
465+
const float rMid = rMin + (rMax - rMin) / 2;
466+
467+
if (cellType == "a") {
468+
// "a"-type cell
469+
//
470+
// Initial placement:
471+
//
472+
// y
473+
// ^
474+
// | 1******
475+
// | ************5
476+
// | 7*****************
477+
// | *********************3
478+
// | *******************
479+
// | 2**************8
480+
// | 6********
481+
// | **4
482+
// |
483+
// |
484+
// | O
485+
// ------------------------> x
486+
//
487+
// * = cell volume
488+
// numbers = hole numbers (as numbered in the code below)
489+
// O = beam pipe
490+
491+
const std::string aCellName = createVolumeName(cellType + sCellName + "a", ring);
492+
493+
// Base shape
494+
const std::string aCellShapeName = aCellName + "Shape";
495+
496+
// The cells in the innermost ring have a slightly shifted inner radius origin.
497+
if (ring == 0) {
498+
// The innermost "a"-type cell
499+
const std::string a1CellShapeFullName = aCellShapeName + "Full";
500+
const std::string a1CellShapeHoleCutName = aCellShapeName + "HoleCut";
501+
const std::string a1CellShapeHoleCutTransName = a1CellShapeHoleCutName + "Trans";
502+
503+
if (!gGeoManager->GetListOfShapes()->Contains((a1CellShapeFullName.c_str()))) {
504+
new TGeoTubeSeg(a1CellShapeFullName.c_str(), 0, mRMaxScintillator[ring], zThickness / 2 - sEpsilon, 45, 90);
505+
}
506+
507+
if (!gGeoManager->GetListOfShapes()->Contains((a1CellShapeHoleCutName.c_str()))) {
508+
new TGeoTube(a1CellShapeHoleCutName.c_str(), 0, mRMinScintillator[ring], zThickness);
509+
}
510+
511+
if (!gGeoManager->GetListOfMatrices()->Contains((a1CellShapeHoleCutTransName.c_str()))) {
512+
createAndRegisterTrans(a1CellShapeHoleCutTransName, sXShiftInnerRadiusScintillator, 0, 0);
513+
}
514+
515+
const std::string a1BoolFormula = a1CellShapeFullName + "-" + a1CellShapeHoleCutName + ":" + a1CellShapeHoleCutTransName;
516+
517+
if (!gGeoManager->GetListOfShapes()->Contains((aCellShapeName.c_str()))) {
518+
new TGeoCompositeShape(aCellShapeName.c_str(), a1BoolFormula.c_str());
519+
}
520+
} else {
521+
// The rest of the "a"-type cells
522+
if (!gGeoManager->GetListOfShapes()->Contains((aCellShapeName.c_str()))) {
523+
new TGeoTubeSeg(aCellShapeName.c_str(), mRMinScintillator[ring], mRMaxScintillator[ring], zThickness / 2, 45, 90);
524+
}
525+
}
526+
527+
}
528+
}
529+
414530
void Geometry::initializeCells(const std::string& cellType, const float zThickness, const TGeoMedium* medium,
415531
const bool isSensitive)
416532
{
@@ -699,7 +815,7 @@ void Geometry::initializeCells(const std::string& cellType, const float zThickne
699815
mSensitiveVolumeNames.push_back(aCell->GetName());
700816
mSensitiveVolumeNames.push_back(bCell->GetName());
701817
}
702-
}
818+
} // for each ring
703819
}
704820

705821
void Geometry::initializeScintCells()
@@ -714,6 +830,12 @@ void Geometry::initializePlasticCells()
714830
initializeCells(sPlasticName, sDzPlastic, medium, false);
715831
}
716832

833+
void Geometry::initializePhotonFilter()
834+
{
835+
const TGeoMedium* medium = gGeoManager->GetMedium("FV0_PhotonFilter$");
836+
initializeCells(sPhotonFilterName, sDzPhotonFilter, medium, false);
837+
}
838+
717839
void Geometry::initializePmts()
718840
{
719841
const TGeoMedium* medium = gGeoManager->GetMedium("FV0_PMT$");
@@ -1048,6 +1170,9 @@ void Geometry::assembleNonSensVols(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left)
10481170
if (mEnabledComponents.at(ePlastics)) {
10491171
assemblePlasticSectors(vFV0Right, vFV0Left);
10501172
}
1173+
if (mEnabledComponents.at(ePhotonFilter)) {
1174+
assemblePhotonFilters(vFV0Right, vFV0Left);
1175+
}
10511176
if (mEnabledComponents.at(ePmts)) {
10521177
assemblePmts(vFV0Right, vFV0Left);
10531178
}
@@ -1085,6 +1210,14 @@ void Geometry::assemblePlasticSectors(TGeoVolume* vFV0Right, TGeoVolume* vFV0Lef
10851210
vFV0Left->AddNode(sectors, 1, trans);
10861211
}
10871212

1213+
void Geometry::assemblePhotonFilters(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left) const
1214+
{
1215+
TGeoVolumeAssembly* sectors = buildSectorAssembly(sPhotonFilterName);
1216+
1217+
vFV0Right->AddNode(sectors, 0);
1218+
vFV0Left->AddNode(sectors, 1);
1219+
}
1220+
10881221
void Geometry::assemblePmts(TGeoVolume* vFV0Right, TGeoVolume* vFV0Left) const
10891222
{
10901223
TGeoVolumeAssembly* pmts = new TGeoVolumeAssembly(createVolumeName("PMTS").c_str());

Detectors/FIT/FV0/simulation/include/FV0Simulation/Detector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class Detector : public o2::base::DetImpl<Detector>
8484
Zero,
8585
Air,
8686
Scintillator,
87+
PhotonFilter,
8788
Plastic,
8889
FiberRing1,
8990
FiberRing2,

Detectors/FIT/FV0/simulation/src/Detector.cxx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,13 @@ void Detector::createMaterials()
175175
Float_t wScint[nScint] = {0.07085, 0.92915}; // based on EJ-204 datasheet: n_atoms/cm3
176176
const Float_t dScint = 1.023;
177177

178+
// Teflon (PTFE) - C2F4, for the photon filter, i.e. the tape/paint between scintillators
179+
const Int_t nTeflon = 2;
180+
Float_t aTeflon[nTeflon] = {12.0107, 19.0};
181+
Float_t zTeflon[nTeflon] = {6, 9};
182+
Float_t wTeflon[nTeflon] = {0.33333, 0.66667};
183+
const Float_t dTeflon = 2.2;
184+
178185
// PMMA plastic mixture: (C5O2H8)n, same for plastic fiber support and for the fiber core
179186
// Fiber cladding is different, but it comprises only 3% of the fiber volume, so it is not included
180187
const Int_t nPlast = 3;
@@ -236,6 +243,10 @@ void Detector::createMaterials()
236243
o2::base::Detector::Medium(Scintillator, "Scintillator$", matId, unsens, fieldType, maxField,
237244
tmaxfd, stemax, deemax, epsil, stmin);
238245

246+
o2::base::Detector::Mixture(++matId, "PhotonFilter$", aTeflon, aTeflon, dTeflon, nTeflon, wTeflon);
247+
o2::base::Detector::Medium(PhotonFilter, "PhotonFilter$", matId, unsens, fieldType, maxField,
248+
tmaxfd, stemax, deemax, epsil, stmin);
249+
239250
o2::base::Detector::Mixture(++matId, "Plastic$", aPlast, zPlast, dPlast, nPlast, wPlast);
240251
o2::base::Detector::Medium(Plastic, "Plastic$", matId, unsens, fieldType, maxField,
241252
tmaxfd, stemax, deemax, epsil, stmin);

Detectors/FIT/common/dcsmonitoring/README.md

Whitespace-only changes.

Detectors/FIT/macros/readFITDCSdata.C

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12-
/// \file readFITDCSdata.C
13-
/// \brief ROOT macro for reading the FIT DCS data from CCDB
12+
/// \file readFITDCSdata.C
13+
/// \brief ROOT macro for reading the FIT DCS datapoint data from CCDB
1414
///
15-
/// \author Andreas Molander <[email protected]>, University of Jyvaskyla, Finland
15+
/// \author Andreas Molander <[email protected]>
1616

1717
#if !defined(__CLING__) || defined(__ROOTCLING__)
1818

@@ -47,11 +47,12 @@
4747

4848
// Helper functions
4949

50+
///
5051
const std::string epochToReadable(const long timestamp);
5152
std::vector<std::string> getAliases(const std::string& input, const o2::ccdb::CcdbApi& ccdbApi, const std::string& detectorName, const long timestamp);
5253
void plotFITDCSmultigraph(const TMultiGraph& multiGraph);
5354

54-
/// ROOT macro for reading FIT DCS data from CCDB.
55+
/// ROOT macro for reading FIT DCS datapoint data from CCDB.
5556
///
5657
/// The macro can:
5758
/// - Plot the trends (default ON)
@@ -181,7 +182,7 @@ void readFITDCSdata(std::string detectorName = "FT0",
181182
}
182183

183184
// The CCDB object should always contain values for all datapoints. This is just to check that.
184-
if (verbose && ((detectorName == "FT0" && ccdbMap->size() != 501) || (detectorName == "FV0" && ccdbMap->size() != 147) || (detectorName == "FDD" && ccdbMap->size() != 76))) {
185+
if (verbose && ((detectorName == "FT0" && ccdbMap->size() != 500) || (detectorName == "FV0" && ccdbMap->size() != 147) || (detectorName == "FDD" && ccdbMap->size() != 99))) {
185186
LOGP(error,
186187
"Wrong number of DCS datapoints fetched for {}, got {}. There is a bug, please send output of this script, with input parameters, to [email protected].",
187188
detectorName, ccdbMap->size());
@@ -353,8 +354,12 @@ void printCCDBObject(const std::string detectorName = "FT0",
353354
}
354355
std::stringstream tmp;
355356
tmp << it.first;
356-
LOGP(info, "DPID = {}", tmp.str());
357-
it.second.print();
357+
// LOGP(info, "DPID = {}", tmp.str());
358+
// LOGP(info, "{}", tmp.str());
359+
// it.second.print();
360+
if (!it.second.empty()) {
361+
LOGP(info, "{} {}", tmp.str(), epochToReadable(it.second.values.back().first));
362+
}
358363
}
359364

360365
LOGP(info, "Size of map = {}", map->size());
@@ -374,6 +379,9 @@ void plotFITDCSmultigraph(const TMultiGraph& multiGraph)
374379
canvas->BuildLegend();
375380
}
376381

382+
/// Convert UNIX timestamp (in ms) to a human readable string.
383+
/// \param timestamp UNIX timestamp in ms.
384+
/// \return Human readable string.
377385
const std::string epochToReadable(const long timestamp)
378386
{
379387
std::string readableTime;
@@ -383,6 +391,10 @@ const std::string epochToReadable(const long timestamp)
383391
return readableTime;
384392
}
385393

394+
/// Parse the input string and return a vector of aliases.
395+
/// If the input string is a file name, the aliases are assumed to be stored in the file, one on each line.
396+
/// If the input string is not a file name, it is assumed to be a semicolon separated list of aliases.
397+
/// If the input string is empty, all data points defined in [ccdbUrl]/[detectorName]/Config/DCSDPconfig are queried.
386398
std::vector<std::string> getAliases(const std::string& input, const o2::ccdb::CcdbApi& ccdbApi, const std::string& detectorName, const long timestamp)
387399
{
388400
std::vector<std::string> aliases;

0 commit comments

Comments
 (0)