Skip to content

Commit 83b5e2f

Browse files
authored
Merge pull request #1842 from brownd1978/oextrap
Migrate KinematicLine_Fit and CentralHelix_Fit to use KKExtrap.
2 parents 3d6f2fe + c6c5464 commit 83b5e2f

32 files changed

Lines changed: 558 additions & 485 deletions

.muse

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# prefer to build with this environment
2-
ENVSET p096
2+
ENVSET p101
33
# add Offline/bin to path
44
PATH bin
55
# recent commits can take enforce these flags

DataProducts/inc/SurfaceId.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace mu2e {
2020
IPA=90, IPA_Front, IPA_Back,
2121
OPA=95, TSDA, // Absorbers in the DS
2222
ST_Front=100,ST_Back, ST_Inner, ST_Outer, ST_Foils, ST_Wires, // stopping target bounding surfaces and components
23-
TCRV=200 // CRV test planes
23+
TCRV=200, CRV_EX, CRV_T1, CRV_T2// CRV test planes (deprecated)
2424
};
2525

2626
static std::string const& typeName();

DataProducts/src/SurfaceId.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ namespace mu2e {
3434
std::make_pair(SurfaceIdEnum::ST_Inner, "ST_Inner"),
3535
std::make_pair(SurfaceIdEnum::ST_Outer, "ST_Outer"),
3636
std::make_pair(SurfaceIdEnum::ST_Foils, "ST_Foils"),
37-
std::make_pair(SurfaceIdEnum::TCRV, "TCRV")
37+
std::make_pair(SurfaceIdEnum::TCRV, "TCRV"),
38+
// separate IDs for each CRV sector
39+
std::make_pair(SurfaceIdEnum::CRV_EX, "CRV_EX"),
40+
std::make_pair(SurfaceIdEnum::CRV_T1, "CRV_T1"),
41+
std::make_pair(SurfaceIdEnum::CRV_T2, "CRV_T2")
3842
};
3943
std::map<SurfaceIdEnum::enum_type,std::string> const& SurfaceIdDetail::names(){
4044
return nam;

GeometryService/inc/GeometryService.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public:
6161
fhicl::Atom<int> configStatsVerbosity{Name("configStatsVerbosity"),false};
6262
fhicl::Atom<bool> printConfig{Name("printConfig"),false};
6363
fhicl::Atom<bool> printConfigTopLevel{Name("printConfigTopLevel"),false};
64+
fhicl::Atom<int> debugLevel{Name("debugLevel"),0};
6465
fhicl::Table<SimulatedDetector> simulatedDetector{Name("simulatedDetector")};
6566
fhicl::Table<KKMaterialConfig> matSettings{Name("KinKalMaterial")};
6667
};
@@ -126,6 +127,7 @@ private:
126127
// Print final config file after all replacements. These affect both SimpleConfig objects.
127128
bool _printConfig;
128129
bool _printTopLevel;
130+
int _debugLevel;
129131

130132
// The objects that parse the run-time configuration files.
131133
std::unique_ptr<SimpleConfig> _config;

GeometryService/inc/KinKalGeomMaker.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
namespace mu2e {
1010
class KinKalGeomMaker {
1111
public:
12+
KinKalGeomMaker(int debug) : debug_(debug) {}
1213
std::unique_ptr<KinKalGeom>& makeKKG();
1314
private:
1415
void makeTracker();
1516
void makeDS();
1617
void makeTarget();
17-
void makeTCRV();
18+
void makeCRV();
1819
std::unique_ptr<KinKalGeom> kkg_;
20+
int debug_ = 0;
1921
};
2022
}
2123
#endif

GeometryService/src/GeometryService.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ namespace mu2e {
106106
_configStatsVerbosity( pars().configStatsVerbosity()),
107107
_printConfig( pars().printConfig()),
108108
_printTopLevel( pars().printConfigTopLevel()),
109+
_debugLevel( pars().debugLevel()),
109110
_config(nullptr),
110111
_simulatedDetector( pars.get_PSet().get<fhicl::ParameterSet>("simulatedDetector")),
111112
_kkMat( pars().matSettings()),
@@ -353,7 +354,7 @@ namespace mu2e {
353354
addDetector( std::move(dusafMu2e) );
354355

355356
// build KinKalGeom, used in track reconstruction and extrapolation
356-
KinKalGeomMaker kkgm;
357+
KinKalGeomMaker kkgm(_debugLevel);
357358
addDetector( std::move(kkgm.makeKKG()) );
358359
// directly build KKMaterial; it's constructor does everything
359360
auto trkptr = getElement<Tracker>();

GeometryService/src/KinKalGeomMaker.cc

Lines changed: 128 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@
44
//
55
#include "Offline/GeometryService/inc/KinKalGeomMaker.hh"
66
#include "Offline/TrackerGeom/inc/Tracker.hh"
7+
#include "Offline/CosmicRayShieldGeom/inc/CosmicRayShield.hh"
78
#include "Offline/GeometryService/inc/GeomHandle.hh"
89
#include "Offline/KinKalGeom/inc/KinKalGeom.hh"
910
#include "Offline/KinKalGeom/inc/Tracker.hh"
1011
#include "Offline/KinKalGeom/inc/DetectorSolenoid.hh"
1112
#include "Offline/KinKalGeom/inc/StoppingTarget.hh"
12-
#include "Offline/KinKalGeom/inc/TestCRV.hh"
13+
#include "Offline/KinKalGeom/inc/CRV.hh"
1314
#include "Offline/BeamlineGeom/inc/Beamline.hh"
1415
#include "Offline/GeometryService/inc/DetectorSystem.hh"
1516
#include "Offline/DetectorSolenoidGeom/inc/DetectorSolenoid.hh"
17+
#include "cetlib_except/exception.h"
18+
#include <cmath>
19+
#include <algorithm>
1620

1721
namespace mu2e {
1822
using KinKal::VEC3;
@@ -29,37 +33,45 @@ namespace mu2e {
2933
using FruPtr = std::shared_ptr<KinKal::Frustrum>;
3034
using SurfacePtr = std::shared_ptr<KinKal::Surface>;
3135
using KKGMap = std::multimap<SurfaceId,SurfacePtr>;
36+
using mu2e::KKGeom::KKCRVSector;
37+
3238

3339
std::unique_ptr<KinKalGeom>& KinKalGeomMaker::makeKKG() {
3440
kkg_ = std::make_unique<KinKalGeom>();
3541
makeTracker();
3642
makeDS();
3743
makeTarget();
38-
makeTCRV();
44+
makeCRV();
3945
return kkg_;
4046
}
4147

48+
// sort by transverse distance
49+
struct sortCRVSectors {
50+
bool operator () (KKCRVSector const& sect1, KKCRVSector const& sect2) {
51+
return sect1.sector_->center().Rho() > sect2.sector_->center().Rho(); // put largest distance first as cosmic rays (generally) go outside-in (downwards)
52+
}
53+
}crvsectorsort;
54+
4255
void KinKalGeomMaker::makeTracker() {
4356
// surfaces need to match with virtual detectors. The following is extracted from VirtualDetectorMaker and needs to be updated if that changes.
4457
// Note that these are placed at the center of the VDs, which have half-thickness of 0.01mm. Since the VD hits are recorded where the SimParticle
4558
// enters the volume, the reco track will be sampled at a different position depending on the track direction by that amount. This is a fundamental
4659
// discrepancy between reco and sim data
4760
auto const& tracker = *(GeomHandle<mu2e::Tracker>());
48-
GeomHandle<Beamline> bg;
49-
GeomHandle<DetectorSystem> det;
50-
GeomHandle<DetectorSolenoid> ds;
61+
auto const& g4tmom = tracker.g4Tracker()->mother();
62+
auto const& ds = *(GeomHandle<DetectorSolenoid>());
5163
double vdHL(0.01); // hardcoded in VirtualDetectorMaker line 56
5264
// below are from VirtualDetectorMaker lnes 241-244
53-
double zFrontGlobal = tracker.g4Tracker()->mother().position().z()-tracker.g4Tracker()->mother().tubsParams().zHalfLength()-vdHL;
54-
double zBackGlobal = tracker.g4Tracker()->mother().position().z()+tracker.g4Tracker()->mother().tubsParams().zHalfLength()+vdHL;
65+
double zFrontGlobal = g4tmom.position().z()-g4tmom.tubsParams().zHalfLength()-vdHL;
66+
double zBackGlobal = g4tmom.position().z()+g4tmom.tubsParams().zHalfLength()+vdHL;
5567
// the 0.4 below comes from offsets in the mother volume nesting.
5668
double zFrontLocal = zFrontGlobal - tracker.g4Tracker()->z0() + 0.4;
5769
double zBackLocal = zBackGlobal - tracker.g4Tracker()->z0() - 0.4;
5870
double zMidLocal = 10.1; // 10.1 is hard-coded in VirtualDetectorMaker line 224
5971
double halfLen = 0.5*(zBackLocal-zFrontLocal);
60-
double orvd = tracker.g4Tracker()->mother().tubsParams().outerRadius();
72+
double orvd = g4tmom.tubsParams().outerRadius();
6173
double irvd = tracker.g4Tracker()->getInnerTrackerEnvelopeParams().innerRadius();
62-
double irds = ds->rIn1();
74+
double irds = ds.rIn1();
6375
// cylinders are defined by TT_outer (_inner) virtual detectors
6476
// Disks are defined to match TT_front (mid, back) virtual detectors
6577
auto outer = std::make_shared<Cylinder>(VEC3(0.0,0.0,1.0),VEC3(0.0,0.0,zMidLocal),orvd,halfLen);
@@ -160,16 +172,113 @@ namespace mu2e {
160172
kkg_->st_ = std::make_unique<KKGeom::StoppingTarget>(outer,inner,front,back,foils);
161173
}
162174

163-
void KinKalGeomMaker::makeTCRV() {
164-
// currently use hard-coded geometry
165-
auto ex1= std::make_shared<Rectangle>(VEC3(0.0,1.0,0.0),VEC3(1.0,0.0,0.0), VEC3(0.0,4775,-438),3000,1675); // layer widths are approximate FIXME
166-
auto t1= std::make_shared<Rectangle>(VEC3(0.0,1.0,0.0),VEC3(0.0,0.0,1.0), VEC3(0.0,4625,-438),1185,850);
167-
auto t2= std::make_shared<Rectangle>(VEC3(0.0,1.0,0.0),VEC3(1.0,0.0,0.0), VEC3(0.0,4925,-438),1600,850);
168-
169-
kkg_->map_.emplace(std::make_pair(SurfaceId(SurfaceIdEnum::TCRV,0),std::static_pointer_cast<Surface>(t1)));
170-
kkg_->map_.emplace(std::make_pair(SurfaceId(SurfaceIdEnum::TCRV,1),std::static_pointer_cast<Surface>(ex1)));
171-
kkg_->map_.emplace(std::make_pair(SurfaceId(SurfaceIdEnum::TCRV,2),std::static_pointer_cast<Surface>(t2)));
175+
void KinKalGeomMaker::makeCRV() {
176+
GeomHandle<CosmicRayShield> CRS;
177+
GeomHandle<DetectorSystem> det;
178+
auto const& shields = CRS->getCRSScintillatorShields();
179+
std::vector<KKCRVSector> sectors;
180+
// loop over the shields (= sectors)
181+
for (auto const& shield : shields) {
182+
//
183+
// First find this shield's orientation; the first bar is enough for that
184+
//
185+
auto const& firstbar = shield.getFirstBar();
186+
auto fbarpos = VEC3(det->toDetector(firstbar.getPosition())); // convert to detector (tracker) coordinates and root vectors
187+
auto bardet = firstbar.getBarDetail();
188+
// normal (w) direction is the thickness direction. Make sure it points away from the tracker
189+
VEC3 wdir;
190+
switch(bardet.getThicknessDirection()) {
191+
case 0:
192+
wdir = VEC3(copysign(1.0,fbarpos.X()),0.0,0.0);
193+
break;
194+
case 1:
195+
wdir = VEC3(0.0,copysign(1.0,fbarpos.Y()),0.0);
196+
break;
197+
case 2:
198+
wdir = VEC3(0.0,0.0,copysign(1.0,fbarpos.Z()));
199+
break;
200+
default:
201+
throw cet::exception("Service")<<"invalid direction "<< bardet.getThicknessDirection() << std::endl;
202+
break;
203+
}
204+
// u direction points along the bars (length direction). Sign is unimportant.
205+
VEC3 udir;
206+
switch(bardet.getLengthDirection()) {
207+
case 0:
208+
udir = VEC3(1.0,0.0,0.0);
209+
break;
210+
case 1:
211+
udir = VEC3(0.0,1.0,0.0);
212+
break;
213+
case 2:
214+
udir = VEC3(0.0,0.0,1.0);
215+
break;
216+
default:
217+
throw cet::exception("Service")<<"invalid direction "<< bardet.getLengthDirection() << std::endl;
218+
break;
219+
}
220+
// v points along bar width
221+
VEC3 vdir;
222+
switch(bardet.getWidthDirection()) {
223+
case 0:
224+
vdir = VEC3(1.0,0.0,0.0);
225+
break;
226+
case 1:
227+
vdir = VEC3(0.0,1.0,0.0);
228+
break;
229+
case 2:
230+
vdir = VEC3(0.0,0.0,1.0);
231+
break;
232+
default:
233+
throw cet::exception("Service")<<"invalid direction "<< firstbar.getBarDetail().getWidthDirection() << std::endl;
234+
break;
235+
}
236+
// next compute the average position. All the bars have the same position along their length
237+
double upos = fbarpos.Dot(udir);
238+
double uhw = firstbar.getHalfLength();
239+
// average first and last layers to get the w position and half-width
240+
auto const& firstmod = shield.getModule(0);
241+
auto flaypos = VEC3(det->toDetector(firstmod.getLayer(0).getPosition()));
242+
auto llaypos = VEC3(det->toDetector(firstmod.getLayer(firstmod.nLayers()-1).getPosition()));
243+
double wpos = 0.5*(flaypos+llaypos).Dot(wdir);
244+
double whw = 0.5*(llaypos-flaypos).Dot(wdir) + firstbar.getHalfThickness();
245+
// include the layer stagger when computing the position and width perp to the bars
246+
auto nlay = firstmod.nLayers();
247+
auto nbar = firstmod.getLayer(0).nBars();
248+
auto const& lastmod = shield.getModule(shield.nModules()-1);
249+
auto vf0 = VEC3(det->toDetector(firstmod.getLayer(0).getBar(0).getPosition())).Dot(vdir);
250+
auto vf3 = VEC3(det->toDetector(firstmod.getLayer(nlay-1).getBar(0).getPosition())).Dot(vdir);
251+
auto vl0 = VEC3(det->toDetector(lastmod.getLayer(0).getBar(nbar-1).getPosition())).Dot(vdir);
252+
auto vl3 = VEC3(det->toDetector(lastmod.getLayer(nlay-1).getBar(nbar-1).getPosition())).Dot(vdir);
253+
double vpos = 0.25*(vf0+vf3+vl0+vl3);
254+
double vmin = std::min({vf0,vf3,vl0,vl3});
255+
double vmax = std::max({vf0,vf3,vl0,vl3});
256+
double vhw = 0.5*(vmax-vmin)+ firstbar.getHalfWidth();
257+
VEC3 midpoint = upos*udir + vpos*vdir + wpos*wdir;
258+
// create the rectangle
259+
KKCRVSector sector;
260+
sector.sname_ = shield.getName();
261+
sector.sector_ = std::make_shared<KinKal::Rectangle>(wdir,udir,midpoint,uhw,vhw);
262+
sector.whw_ = whw;
263+
sectors.push_back(sector);
264+
}
265+
// sort the sectors according to their transverse distance (largest first), to optimize searching for downward going tracks.
266+
std::sort(sectors.begin(),sectors.end(),crvsectorsort);
267+
if(debug_ > 0){
268+
for(auto const& sector : sectors){
269+
std::cout << "CRV sector " << sector.sname_;
270+
auto const& sectptr = sector.sector_;
271+
std::cout << " midpoint " << sectptr->center() << " wdir " << sectptr->normal() << " udir " << sectptr->uDirection() << " vdir " << sectptr->vDirection()
272+
<< " uhw " << sectptr->uHalfLength() << " vhw " << sectptr->vHalfLength() << " whw " << sector.whw_ << std::endl;
273+
}
274+
}
172275

173-
kkg_->tcrv_ = std::make_unique<KKGeom::TestCRV>(ex1,t1,t2);
276+
kkg_->crv_ = std::make_unique<KKGeom::CRV>(sectors);
277+
// fill map
278+
unsigned isect(0);
279+
for(auto const& sector : kkg_->crv_->sectors()){
280+
kkg_->map_.emplace(std::make_pair(SurfaceId(sector.sname_),std::static_pointer_cast<Surface>(sector.sector_)));
281+
isect++;
282+
}
174283
}
175284
}

KinKalGeom/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
cet_make_library(
22
SOURCE
3-
src/CRV.cc
43
src/KinKalGeom.cc
54
src/KKMaterial.cc
65
src/KKStrawMaterial.cc

KinKalGeom/fcl/prolog.fcl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ KinKalGeom : {
99
strawWireMaterialName : "straw-wire"
1010
IPAMaterialName : "HDPE"
1111
STMaterialName : "Target"
12+
CRVMaterialName : "CRVModule"
1213
IonizationEnergyLossMode : 1 # Moyal mean
1314
SolidScatteringFraction : 0.999999
1415
GasScatteringFraction : 0.9999999

KinKalGeom/inc/CRV.hh

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,23 @@
99
#include <memory>
1010
namespace mu2e {
1111
namespace KKGeom {
12+
using RecPtr = std::shared_ptr<KinKal::Rectangle>;
13+
struct KKCRVSector {
14+
std::string sname_;
15+
RecPtr sector_;
16+
double whw_;
17+
};
1218
class CRV {
13-
public:
14-
using RecPtr = std::shared_ptr<KinKal::Rectangle>;
15-
// default constructor with nominal geometry
16-
CRV();
17-
// accessors
18-
// return by reference
19-
auto const& rightSectorBlock() const { return *rightSectorBlock_; }
20-
auto const& rightSectorHole() const { return *rightSectorHole_; }
21-
auto const& cryoSectorHole() const { return *cryoSectorHole_; }
22-
auto const& leftSectorBlock() const { return *leftSectorBlock_; }
23-
auto const& leftSectorHole() const { return *leftSectorHole_; }
24-
auto const& topSectorBlock() const { return *topSectorBlock_; }
25-
auto const& extSectorBlock() const { return *extSectorBlock_; }
26-
auto const& upstreamSector1() const { return *upstreamSectorBlock_; }
27-
auto const& downstreamSectorBlock() const { return *downstreamSectorBlock_; }
28-
auto const& downstreamSectorHole() const { return *downstreamSectorHole_; }
29-
auto const& cryoSector1() const { return *cryoSector1_; }
30-
auto const& cryoSector2() const { return *cryoSector2_; }
31-
//
32-
auto const& rightSectorBlockPtr() const { return rightSectorBlock_; }
33-
auto const& rightSectorHolePtr() const { return rightSectorHole_; }
34-
auto const& cryoSectorHolePtr() const { return cryoSectorHole_; }
35-
auto const& leftSectorBlockPtr() const { return leftSectorBlock_; }
36-
auto const& leftSectorHolePtr() const { return leftSectorHole_; }
37-
auto const& topSectorBlockPtr() const { return topSectorBlock_; }
38-
auto const& extSectorBlockPtr() const { return extSectorBlock_; }
39-
auto const& upstreamSectorBlockPtr() const { return upstreamSectorBlock_; }
40-
auto const& downstreamSectorBlockPtr() const { return downstreamSectorBlock_; }
41-
auto const& downstreamSectorHolePtr() const { return downstreamSectorHole_; }
42-
auto const& cryoSector1Ptr() const { return cryoSector1_; }
43-
auto const& cryoSector2Ptr() const { return cryoSector2_; }
19+
public:
20+
// construct with rectangles representing the midplane of CRV sectors (shields)
21+
CRV(std::vector<KKCRVSector> const& sectors) : sectors_(sectors) {}
22+
// accessors
23+
auto const& sectors() const { return sectors_; }
24+
auto const& sector(size_t isect) const { return sectors_[isect].sector_; }
25+
auto const& sectorName(size_t isect) const { return sectors_[isect].sname_; }
26+
auto const& sectorHalfWidth(size_t isect) const { return sectors_[isect].whw_; }
4427
private:
45-
RecPtr rightSectorBlock_, rightSectorHole_, cryoSectorHole_, leftSectorBlock_, leftSectorHole_, topSectorBlock_, extSectorBlock_, upstreamSectorBlock_, downstreamSectorBlock_, downstreamSectorHole_, cryoSector1_, cryoSector2_;
28+
std::vector<KKCRVSector> sectors_;
4629
};
4730
}
4831
}

0 commit comments

Comments
 (0)