15#include "FairGeoBuilder.h"
16#include "FairGeoInterface.h"
17#include "FairGeoLoader.h"
18#include "FairGeoMedia.h"
19#include "FairGeoNode.h"
20#include "FairGeoVolume.h"
21#include "FairLogger.h"
22#include "FairRootManager.h"
24#include "FairRuntimeDb.h"
25#include "FairVolume.h"
29#include "TClonesArray.h"
31#include "TGeoCompositeShape.h"
32#include "TGeoManager.h"
33#include "TGeoMaterial.h"
34#include "TGeoMedium.h"
39#include "TVirtualMC.h"
45 : Detector(
"strawtubes", kTRUE,
kStraw), fMedium(
"air") {}
48 : Detector(
"strawtubes", kTRUE,
kStraw), fMedium(medium) {}
51 : Detector(name, active,
kStraw) {}
56 if (gMC->IsTrackEntering()) {
58 fTime = gMC->TrackTime() * 1.0e09;
60 gMC->TrackPosition(
fPos);
61 gMC->TrackMomentum(
fMom);
67 if (gMC->IsTrackExiting() || gMC->IsTrackStop() ||
68 gMC->IsTrackDisappeared()) {
72 TParticle* p = gMC->GetStack()->GetCurrentTrack();
73 Int_t pdgCode = p->GetPdgCode();
74 fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
77 gMC->CurrentVolID(straw_uniqueId);
89 gMC->TrackPosition(Pos);
90 Double_t xmean = (
fPos.X() + Pos.X()) / 2.;
91 Double_t ymean = (
fPos.Y() + Pos.Y()) / 2.;
92 Double_t zmean = (
fPos.Z() + Pos.Z()) / 2.;
93 TVector3 pq = TVector3(top.x() - xmean, top.y() - ymean, top.z() - zmean);
95 TVector3(bot.x() - top.x(), bot.y() - top.y(), bot.z() - top.z());
97 TVector3(
fPos.X() - Pos.X(),
fPos.Y() - Pos.Y(),
fPos.Z() - Pos.Z());
98 TVector3 uCrossv = u.Cross(v);
99 Double_t dist2Wire = fabs(pq.Dot(uCrossv)) / (uCrossv.Mag() + 1
E-8);
100 Double_t deltaTrackLength = gMC->TrackLength() -
fLength;
103 fELoss, pdgCode, dist2Wire);
105 std::cout <<
"addhit " << dist2Wire <<
" straw id " << straw_uniqueId
106 <<
" pdgcode " << pdgCode <<
" dot prod " << pq.Dot(uCrossv)
108 std::cout <<
" exit:" << gMC->IsTrackExiting()
109 <<
" stop:" << gMC->IsTrackStop()
110 <<
" disappeared:" << gMC->IsTrackDisappeared() << std::endl;
111 std::cout <<
" entry:" <<
fPos.X() <<
" " <<
fPos.Y() <<
" " <<
fPos.Z()
113 std::cout <<
" exit:" << Pos.X() <<
" " << Pos.Y() <<
" " << Pos.Z()
115 std::cout <<
" mean:" << xmean <<
" " << ymean <<
" " << zmean
117 std::cout <<
" bot:" << bot.x() <<
" " << bot.y() <<
" " << bot.z()
119 std::cout <<
" top:" << top.x() <<
" " << top.y() <<
" " << top.z()
147 Double_t wall_thickness) {
150 outer_straw_diameter - 2 * wall_thickness;
189 TGeoVolume* top = gGeoManager->GetTopVolume();
191 TGeoMedium* mylar = gGeoManager->GetMedium(
"mylar");
193 TGeoMedium* sttmix8020_1bar = gGeoManager->GetMedium(
"STTmix8020_1bar");
195 TGeoMedium* tungsten = gGeoManager->GetMedium(
"tungsten");
199 TGeoMedium* med = gGeoManager->GetMedium(
fMedium.c_str());
201 gGeoManager->SetVisLevel(4);
202 gGeoManager->SetTopVisible();
205 Double_t eps = 0.0001;
209 Double_t frame_width = 49.;
211 Double_t floor_offset = 14.;
213 Double_t rmin, rmax, T_station_z;
216 [[maybe_unused]] TGeoBBox* detbox1 =
new TGeoBBox(
219 [[maybe_unused]] TGeoBBox* detbox2 =
new TGeoBBox(
220 "detbox2", straw_length + eps,
222 TMath::Tan(
f_view_angle * TMath::Pi() / 180.0) * straw_length * 2 +
225 TGeoTranslation* move_up =
226 new TGeoTranslation(
"move_up", 0, floor_offset / 2., 0);
227 move_up->RegisterYourself();
230 TGeoCompositeShape* detcomp1 =
231 new TGeoCompositeShape(
"detcomp1",
"(detbox1:move_up)-detbox2");
237 TGeoTube* straw_tube =
new TGeoTube(
"straw", rmin, rmax, straw_length);
238 TGeoVolume* straw =
new TGeoVolume(
"straw", straw_tube, mylar);
239 straw->SetLineColor(4);
240 straw->SetVisibility(kTRUE);
245 TGeoTube* gas_tube =
new TGeoTube(
"gas", rmin, rmax, straw_length - 2. * eps);
246 TGeoVolume* gas =
new TGeoVolume(
"gas", gas_tube, sttmix8020_1bar);
247 gas->SetLineColor(5);
249 AddSensitiveVolume(gas);
254 TGeoTube* wire_tube =
255 new TGeoTube(
"wire", rmin, rmax, straw_length - 4. * eps);
256 TGeoVolume* wire =
new TGeoVolume(
"wire", wire_tube, tungsten);
257 wire->SetLineColor(6);
270 for (Int_t statnb = 1; statnb < 5; statnb++) {
272 TString nmstation =
"Tr";
273 std::stringstream ss;
275 nmstation = nmstation + ss.str();
293 TGeoVolume* vol =
new TGeoVolume(nmstation, statbox, med);
295 top->AddNode(vol, statnb,
296 new TGeoTranslation(0, floor_offset / 2., T_station_z));
298 TGeoVolume* statframe =
299 new TGeoVolume(nmstation +
"_frame", detcomp1, FrameMatPtr);
300 vol->AddNode(statframe, statnb * 1e6,
301 new TGeoTranslation(0, -floor_offset / 2., 0));
302 statframe->SetLineColor(kRed);
304 for (Int_t vnb = 0; vnb < 4; vnb++) {
306 const Double_t angle = [&] {
316 const TString nmview = [&] {
319 return nmstation +
"_y1";
321 return nmstation +
"_u";
323 return nmstation +
"_v";
325 return nmstation +
"_y2";
327 return nmstation +
"_y1";
337 const Double_t stereo_growth =
338 TMath::Tan(TMath::Abs(angle) * TMath::Pi() / 180.0) * straw_length;
339 const Double_t stereo_pitch =
340 f_straw_pitch / TMath::Cos(TMath::Abs(angle) * TMath::Pi() / 180.0);
341 const Double_t offset_layer =
342 f_offset_layer / TMath::Cos(TMath::Abs(angle) * TMath::Pi() / 180.0);
343 const Int_t straws_per_layer =
346 for (Int_t lnb = 0; lnb < 2; lnb++) {
348 TString nmlayer = nmview +
"_layer_";
350 TGeoBBox* layer =
new TGeoBBox(
351 "layer box", straw_length + eps / 4,
354 TGeoVolume* layerbox =
new TGeoVolume(nmlayer, layer, med);
359 layerbox, statnb * 1e6 + vnb * 1e5 + lnb * 1e4,
360 new TGeoTranslation(0, -floor_offset / 2.,
366 for (Int_t snb = 1; snb <= straws_per_layer; snb++) {
369 t6s.SetTranslation(0,
371 (snb - 1. / 2.) * stereo_pitch +
375 r6s.SetAngles(90 + angle, 90, 0);
376 TGeoCombiTrans c6s(t6s, r6s);
377 TGeoHMatrix* h6s =
new TGeoHMatrix(c6s);
379 straw, statnb * 1e6 + vnb * 1e5 + lnb * 1e4 + 1e3 + snb, h6s);
381 gas, statnb * 1e6 + vnb * 1e5 + lnb * 1e4 + 2e3 + snb, h6s);
383 wire, statnb * 1e6 + vnb * 1e5 + lnb * 1e4 + 3e3 + snb, h6s);
390 t6s.SetTranslation(0,
392 (straws_per_layer - 1. / 2.) * stereo_pitch -
395 r6s.SetAngles(90 + angle, 90, 0);
396 TGeoCombiTrans c6s(t6s, r6s);
397 TGeoHMatrix* h6s =
new TGeoHMatrix(c6s);
400 statnb * 1e6 + vnb * 1e5 + lnb * 1e4 + 1e3 + straws_per_layer + 1,
404 statnb * 1e6 + vnb * 1e5 + lnb * 1e4 + 2e3 + straws_per_layer + 1,
408 statnb * 1e6 + vnb * 1e5 + lnb * 1e4 + 3e3 + straws_per_layer + 1,
422 Int_t statnb, vnb, lnb, snb;
423 statnb = detID / 1e6;
424 vnb = (detID - statnb * 1e6) / 1e5;
425 lnb = (detID - statnb * 1e6 - vnb * 1e5) / 1e4;
426 snb = detID - statnb * 1e6 - vnb * 1e5 - lnb * 1e4 - 2e3;
428 if (statnb < 1 || statnb > 4 || vnb < 0 || vnb > 3 || lnb < 0 || lnb > 1 ||
429 snb < 1 || snb > 317) {
430 LOG(warning) <<
"Invalid strawtubes detID:";
431 LOG(warning) << detID <<
" -> station: " << statnb <<
", view: " << vnb
432 <<
", layer: " << lnb <<
", straw: " << snb;
433 LOG(warning) <<
"strawtubes detID is 7-digit!";
434 return {0, -1, -1, 0};
436 return {statnb, vnb, lnb, snb};
447 const auto [statnb, vnb, lnb, snb] =
StrawDecode(fDetectorID);
452 const TString view = [&] {
455 return TString(
"_u");
457 return TString(
"_v");
459 return TString(
"_y2");
461 return TString(
"_y1");
464 TGeoNavigator* nav = gGeoManager->GetCurrentNavigator();
465 TString prefix =
"Tr";
469 TString layer = prefix +
"layer_";
476 TString wire =
"wire_";
477 wire += fDetectorID + 1e3;
484 Bool_t rc = nav->cd(path);
486 LOG(warning) <<
"strawtubes::StrawDecode, TGeoNavigator failed" << path;
489 TGeoNode* W = nav->GetCurrentNode();
490 TGeoTube* S =
dynamic_cast<TGeoTube*
>(W->GetVolume()->GetShape());
491 Double_t top[3] = {0, 0, S->GetDZ()};
492 Double_t bot[3] = {0, 0, -S->GetDZ()};
493 Double_t Gtop[3], Gbot[3];
494 nav->LocalToMaster(top, Gtop);
495 nav->LocalToMaster(bot, Gbot);
496 vtop.SetXYZ(Gtop[0], Gtop[1], Gtop[2]);
497 vbot.SetXYZ(Gbot[0], Gbot[1], Gbot[2]);
Int_t fTrackID
event index
Int_t fVolumeID
track index
TLorentzVector fPos
volume id
Double_t fTime
momentum at entrance
strawtubesPoint * AddHit(Args &&... args)
TLorentzVector fMom
position at entrance
void SetDeltazView(Double_t delta_z_view)
std::string fMedium
spatial resolution
Double_t f_aperture_width
z-position of tracking station 4
Double_t f_inner_straw_diameter
Aperture height (y)
Double_t f_station_length
Station envelope height (y)
Bool_t ProcessHits(FairVolume *v=0) override
void SetDeltazLayer(Double_t delta_z_layer)
Double_t f_wire_thickness
Stereo view angle.
Double_t f_T2_z
z-position of tracking station 1
TString f_frame_material
Sense wire thickness.
static void StrawEndPoints(Int_t detID, TVector3 &top, TVector3 &bot)
void SetStrawDiameter(Double_t outer_straw_diameter, Double_t wall_thickness)
void SetzPositions(Double_t z1, Double_t z2, Double_t z3, Double_t z4)
Double_t f_straw_pitch
Outer Straw diameter.
Double_t f_T3_z
z-position of tracking station 2
Double_t f_aperture_height
Aperture width (x)
Double_t f_delta_z_view
Structure frame material.
void SetStrawPitch(Double_t straw_pitch, Double_t layer_offset)
Double_t f_station_height
Station envelope width (x)
void ConstructGeometry() override
Double_t f_view_angle
Distance (z) between layers.
Double_t f_outer_straw_diameter
Inner Straw diameter.
void SetFrameMaterial(TString frame_material)
Double_t f_station_width
Distance (z) between stereo views.
void SetStereoAngle(Double_t stereo_angle)
void SetWireThickness(Double_t wire_thickness)
void SetApertureArea(Double_t width, Double_t height)
void SetStationEnvelope(Double_t x, Double_t y, Double_t z)
static std::array< Int_t, 4 > StrawDecode(Int_t detID)
Double_t f_offset_layer
Distance (y) between straws in a layer.
Double_t f_T4_z
z-position of tracking station 3
Double_t f_delta_z_layer
Offset (y) of straws between layers.
Int_t InitMedium(const char *name)