7 const Int_t kNofDisks = 3;
13 const Double_t kHalfStationThickness = 3.00;
14 const Double_t kDiskInnerRadius[kNofDisks] = { 4.52, 4.52, 4.52};
15 const Double_t kDiskOuterRadius[kNofDisks] = { 37.92, 46.4, 64.4};
16 const Double_t kDiskZPosition [kNofDisks] = {119.6,143.1,175.6};
17 const Int_t kDiskNFoils [kNofDisks] = { 2 , 2 , 4 };
18 const Double_t kMiddleROBarHfTh[kNofDisks] = { 4.3, 4.3, 4.3};
20 const Int_t kNofLayers = 39;
21 const TString kLayerName [kNofLayers] = {
"WindowF_kapton",
"WindowF_aluminium",
23 "CathodeF_kapton",
"CathodeF_aluminium",
24 "Gem1_Sensor_GEMmixture",
25 "Gem1F_copper",
"Gem1_kapton",
"Gem1B_copper",
27 "Gem2F_copper",
"Gem2_kapton",
"Gem2B_copper",
29 "Gem3F_copper",
"Gem3_kapton",
"Gem3B_copper",
31 "PadF_copper",
"Pad_kapton",
"Pad_copper",
33 "Gem4F_copper",
"Gem4_kapton",
"Gem4B_copper",
35 "Gem5F_copper",
"Gem5_kapton",
"Gem5B_copper",
37 "Gem6F_copper",
"Gem6_kapton",
"Gem6B_copper",
38 "Gem6_Sensor_GEMmixture",
39 "CathodeB_aluminium",
"CathodeB_kapton",
41 "WindowB_aluminium",
"WindowB_kapton"};
42 const Double_t kLayerThick[kNofLayers] = { 0.0007, 0.0001,
46 0.0002, 0.0050, 0.0002,
48 0.0002, 0.0050, 0.0002,
50 0.0002, 0.0050, 0.0002,
52 0.0012, 0.0050, 0.0012,
54 0.0002, 0.0050, 0.0002,
56 0.0002, 0.0050, 0.0002,
58 0.0002, 0.0050, 0.0002,
69 const Int_t kSensorStripType [2] = { 3 , 2 };
71 const Double_t kSensorStripAngle[2][2] = { 0. , 0. , 0. , 0. };
72 const Double_t kSensorStripPitch[2][2] = { 0.04, 0.04, 0.04, 0.04};
76 for ( Int_t ilayer = 0 ; ilayer < kNofLayers ; ilayer++ ) {
77 cout << kLayerName[ilayer].Data() <<
" -> " << kLayerThick[ilayer] << endl;
78 firstLayerOffset += kLayerThick[ilayer];
81 cout <<
"total thickness is " << firstLayerOffset << endl;
82 firstLayerOffset = firstLayerOffset/2.;
83 firstLayerOffset = -0.001*(TMath::Floor(1000.*firstLayerOffset));
84 cout <<
"first layer offset is " << firstLayerOffset << endl;
87 TString vmcWorkdir = getenv(
"VMCWORKDIR");
90 TFile*
fi =
new TFile(outfile,
"RECREATE");
92 cout <<
"created output file" << endl;
93 FairGeoLoader*
geoLoad =
new FairGeoLoader(
"TGeo",
"FairGeoLoader");
94 FairGeoInterface *
geoFace = geoLoad->getGeoInterface();
95 cout <<
"geoface setmediafile" << endl;
96 geoFace->setMediaFile(
"../../geometry/media_pnd.geo");
97 cout <<
"geoface readmedia" << endl;
99 cout <<
"geoface print" << endl;
101 cout <<
"geoface done" << endl;
103 FairGeoMedia *
Media = geoFace->getMedia();
104 FairGeoBuilder *
geobuild=geoLoad->getGeoBuilder();
110 FairGeoMedium *CbmMediumCopper = Media->getMedium(
"copper");
111 FairGeoMedium *CbmMediumKapton = Media->getMedium(
"kapton");
112 FairGeoMedium *CbmMediumArCO2 = Media->getMedium(
"GEMmixture");
114 Int_t
nmed=geobuild->createMedium(CbmMediumAir);
115 nmed=geobuild->createMedium(CbmMediumPWO);
116 nmed=geobuild->createMedium(CbmMediumCarbon);
117 nmed=geobuild->createMedium(CbmMediumAluminium);
118 nmed=geobuild->createMedium(CbmMediumCopper);
119 nmed=geobuild->createMedium(CbmMediumKapton);
120 nmed=geobuild->createMedium(CbmMediumArCO2);
122 TGeoManager*
gGeoMan = (TGeoManager*)gROOT->FindObject(
"FAIRGeom");
124 TGeoVolume *
top =
new TGeoVolumeAssembly(
"Gem");
126 gGeoMan->SetTopVolume(top);
128 cout <<
"-------------------------------------------------------------------" << endl;
129 TList* mediaList = (TList*)gGeoMan->GetListOfMedia();
131 cout <<
"media known: " << mediaList->GetEntries() <<
"." << endl;
132 for ( Int_t itemp = 0 ; itemp < mediaList->GetEntries() ; itemp++ ) {
133 TGeoMedium*
medium = (TGeoMedium*)mediaList->At(itemp);
134 cout <<
"medium " << itemp <<
" name is " << medium->GetName() << endl;
136 cout <<
"-------------------------------------------------------------------" << endl;
138 TGeoRotation*
dummyrot =
new TGeoRotation();
140 TGeoVolumeAssembly*
SubunitVol =
new TGeoVolumeAssembly(
"Gem_Disks");
142 TGeoShape *DiskShape[kNofDisks];
143 TGeoVolume *DiskVol [kNofDisks];
144 TGeoTranslation *DiskTrans[kNofDisks];
145 TGeoCombiTrans *DiskCombi[kNofDisks];
147 TGeoShape *DiskLayersShapeA[kNofDisks][kNofLayers][4];
148 TGeoShape *DiskLayersShapeB[kNofDisks][kNofLayers][4];
149 TGeoSubtraction *DiskLayersSubtr [kNofDisks][kNofLayers][4];
150 TGeoShape *DiskLayersShapeC[kNofDisks][kNofLayers][4];
151 TGeoVolume *DiskLayersVol [kNofDisks][kNofLayers][4];
152 TGeoTranslation *DiskLayersTrans[kNofDisks][kNofLayers][4];
153 TGeoCombiTrans *DiskLayersCombi[kNofDisks][kNofLayers][4];
155 TString outParFileName = Form(
"%s/macro/params/gem_3Stations.digi.par",vmcWorkdir.Data());
157 cout <<
"parameter file = \"" << outParFileName.Data() <<
"\"" << endl;
159 ofstream pout(outParFileName.Data());
160 pout.setf(ios::fixed);
162 pout <<
"#################################################################" << endl;
163 pout <<
"# Digitization parameters for GEM " << endl;
164 pout <<
"# with 3 Stations at "
165 << kDiskZPosition[0] <<
", "
166 << kDiskZPosition[1] <<
", "
167 << kDiskZPosition[2] <<
" cm from the target " << endl;
168 pout <<
"# Format: " << endl;
169 pout <<
"#Description of parameters: " << endl;
170 pout <<
"#[PndGemDetectors] " << endl;
171 pout <<
"#parameters:d station_number, ZPos, rotation_angle, number_of_sensors, \\" << endl;
172 pout <<
"# sensor_number, sensor_type, pos_x, pos_y, pos_z, rotAngle, inn_rad, out_rad, thick, str_ang_0, str_ang_1, barWidth, pitch_0, pitch_1, \\" << endl;
173 pout <<
"# sensor_number, ...." << endl;
174 pout <<
"# station_number, ..." << endl;
175 pout <<
"#################################################################" << endl;
176 pout <<
"[PndGemDetectors]" << setprecision(4) << endl;
178 pout <<
"parameters:Double_t \\" << endl;
180 for ( Int_t istat = 0 ; istat < kNofDisks ; istat++ ) {
182 pout <<
" " << istat+1 <<
", "
183 << setw(9) << kDiskZPosition[istat]
184 <<
", 0.0, " << 2 <<
", \\" << endl;
186 DiskShape[istat] =
new TGeoTube (Form(
"disk%dshape",istat+1),kDiskInnerRadius[istat],kDiskOuterRadius[istat],kHalfStationThickness);
187 DiskVol [istat] =
new TGeoVolume(Form(
"Gem_Disk%d_Volume",istat+1),DiskShape[istat],gGeoMan->GetMedium(
"GEMmixture"));
188 DiskTrans[istat] =
new TGeoTranslation(0.,0.,kDiskZPosition[istat]);
189 cout <<
"station " << kDiskInnerRadius[istat] <<
" " << kDiskOuterRadius[istat] <<
" at " << kDiskZPosition[istat] << endl;
190 DiskCombi[istat] =
new TGeoCombiTrans(*DiskTrans[istat],*dummyrot);
191 DiskCombi[istat]->SetName(Form(
"Gem_Disk%d_Volume",istat+1));
192 DiskCombi[istat]->RegisterYourself();
194 Double_t layerPosition = firstLayerOffset;
196 Int_t sensorNumber = 0;
198 for ( Int_t ilay = 0 ; ilay < kNofLayers ; ilay++ ) {
199 layerPosition += kLayerThick[ilay]/2.;
200 if ( kLayerName[ilay].Contains(
"space") && kLayerName[ilay].Length() == 5 ) {
201 layerPosition += kLayerThick[ilay]/2.;
208 for ( Int_t iseg = 0 ; iseg < 1 ; iseg++ ) {
209 DiskLayersShapeA[istat][ilay][iseg] =
new TGeoTube(Form(
"disk%dseg%d%sshape",istat+1,iseg+1,kLayerName[ilay].Data()),
210 kDiskInnerRadius[istat],kDiskOuterRadius[istat],
211 kLayerThick[ilay]/2.);
212 DiskLayersShapeB[istat][ilay][iseg] =
new TGeoBBox (Form(
"robo%dseg%d%sshape",istat+1,iseg+1,kLayerName[ilay].Data()),
213 kMiddleROBarHfTh[istat]/2.,
214 kDiskOuterRadius[istat],
216 DiskLayersSubtr [istat][ilay][iseg] =
new TGeoSubtraction(DiskLayersShapeA[istat][ilay][iseg],
217 DiskLayersShapeB[istat][ilay][iseg]);
218 DiskLayersShapeC[istat][ilay][iseg] =
new TGeoCompositeShape(Form(
"comp%dseg%d%sshape",istat+1,iseg+1,kLayerName[ilay].Data()),
219 DiskLayersSubtr[istat][ilay][iseg]);
220 segBegin += segPhiSpan;
222 TString layerMaterial = kLayerName[ilay].Data();
223 layerMaterial.Remove(0,layerMaterial.Last(
'_')+1);
225 DiskLayersVol [istat][ilay][iseg] =
new TGeoVolume(Form(
"Gem_Disk%d_Seg%d_%s",istat+1,iseg+1,kLayerName[ilay].Data()),
226 DiskLayersShapeC[istat][ilay][iseg],
227 gGeoMan->GetMedium(layerMaterial.Data()));
230 if ( layerMaterial.Contains(
"copper" ) )
232 if ( layerMaterial.Contains(
"kapton" ) )
234 if ( layerMaterial.Contains(
"aluminium" ) )
236 DiskLayersTrans[istat][ilay][iseg] =
new TGeoTranslation(0.,0.,layerPosition);
237 DiskLayersCombi[istat][ilay][iseg] =
new TGeoCombiTrans(*DiskLayersTrans[istat][ilay][iseg],*dummyrot);
238 DiskLayersCombi[istat][ilay][iseg]->SetName(Form(
"Gem_Disk%d_Seg%d_%s",istat+1,iseg+1,kLayerName[ilay].Data()));
239 DiskLayersCombi[istat][ilay][iseg]->RegisterYourself();
240 DiskVol[istat]->AddNode(DiskLayersVol [istat][ilay][iseg],0,DiskLayersCombi[istat][ilay][iseg]);
244 cout <<
"volume " << kLayerName[ilay] <<
" from "
245 << setprecision(10) << kDiskZPosition[istat]+layerPosition-kLayerThick[ilay]/2. <<
" to "
246 << setprecision(10) << kDiskZPosition[istat]+layerPosition+kLayerThick[ilay]/2. << endl;
248 if ( kLayerName[ilay].Contains(
"Gem") && kLayerName[ilay].Contains(
"Sensor") ) {
249 Double_t newRadius = kDiskInnerRadius[istat];
252 cout <<
"rad = " << kDiskInnerRadius[istat] <<
" pitch = " << kSensorStripPitch[sensorNumber][0] <<
" for sensor " << sensorNumber << endl;
253 if ( kSensorStripType[sensorNumber] != 2 ) {
254 nofStrips = TMath::Ceil(2.*
TMath::Pi()*kDiskInnerRadius[istat]/kSensorStripPitch[sensorNumber][0]);
255 newRadius = nofStrips*kSensorStripPitch[sensorNumber][0]/2./
TMath::Pi();
257 cout <<
"!!!! " << istat <<
" " << ilay <<
" > there shall be " << nofStrips <<
" strips here so the radius should be " << newRadius << endl;
258 pout <<
" " << sensorNumber+1 <<
", " << kSensorStripType[sensorNumber] <<
", "
259 << setw(9) << 0. <<
", "
260 << setw(9) << 0. <<
", "
261 << setw(9) << kDiskZPosition[istat]+layerPosition <<
", "
262 << setw(9) << 0. <<
", "
263 << setw(9) << newRadius <<
", "
264 << setw(9) << kDiskOuterRadius[istat] <<
", "
265 << setw(9) << kLayerThick[ilay] <<
", "
266 << setw(9) << kSensorStripAngle[sensorNumber][0] <<
", "
268 << setw(9) << kMiddleROBarHfTh[istat] <<
", "
269 << setw(9) << kSensorStripPitch[sensorNumber][0] <<
", "
270 << setw(9) << kSensorStripPitch[sensorNumber][1] << ((istat==kNofDisks-1&&sensorNumber==1)?
"":
", \\")
275 layerPosition += kLayerThick[ilay]/2.;
277 SubunitVol->AddNode(DiskVol[istat],0,DiskCombi[istat]);
279 pout <<
"TrackFinderOnHits_ParThetaA: Double_t 59.4" << endl
280 <<
"TrackFinderOnHits_ParThetaB: Double_t -0.02" << endl
281 <<
"TrackFinderOnHits_ParTheta0: Double_t 56.1372" << endl
282 <<
"TrackFinderOnHits_ParTheta1: Double_t -0.000564362" << endl
283 <<
"TrackFinderOnHits_ParTheta2: Double_t -0.181828" << endl
284 <<
"TrackFinderOnHits_ParTheta3: Double_t 0.284289" << endl
285 <<
"TrackFinderOnHits_ParRadPhi0:Double_t 0.9944432" << endl
286 <<
"TrackFinderOnHits_ParRadPhi2:Double_t -0.000590706" << endl
287 <<
"TrackFinderOnHits_ParMat0: Double_t \\" << endl
288 <<
" -2.31333e-6, 0.00067035, 0.10173" << endl
289 <<
"TrackFinderOnHits_ParMat1: Double_t \\" << endl
290 <<
" -7.46844e-10, -6.6696e-7, 0.000736672" << endl
291 <<
"##########################################################################################" << flush;
293 top->AddNode(SubunitVol,0,
new TGeoCombiTrans());
295 gGeoMan->CloseGeometry();
FairGeoMedium * CbmMediumCarbon
FairGeoMedium * CbmMediumAluminium
FairGeoBuilder * geobuild
FairGeoMedium * CbmMediumAir
FairGeoMedium * CbmMediumPWO
FairGeoInterface * geoFace
vDisk SetLineColor(colYellow)