00001 #include "G4ThreeVector.hh"
00002
00003 #include "BesEmcEndGeometry.hh"
00004 #include "BesEmcParameter.hh"
00005 #include "G4ios.hh"
00006
00007 #include <iomanip>
00008 #include <fstream>
00009 #include <sstream>
00010 #include <iostream>
00011 #include <assert.h>
00012
00013
00014 using namespace std;
00015
00016 BesEmcEndGeometry::BesEmcEndGeometry()
00017 {;}
00018
00019 BesEmcEndGeometry::~BesEmcEndGeometry()
00020 {;}
00021
00022 void BesEmcEndGeometry::ReadParameters()
00023 {
00024 BesEmcParameter& emcPara=BesEmcParameter::GetInstance();
00025
00026 WorldRmin1 = emcPara.GetWorldRmin1();
00027 WorldRmax1 = emcPara.GetWorldRmax1();
00028 WorldRmin2 = emcPara.GetWorldRmin2();
00029 WorldRmax2 = emcPara.GetWorldRmax2();
00030 WorldDz = emcPara.GetWorldDz();
00031 WorldZPosition = emcPara.GetWorldZPosition();
00032 CrystalLength = emcPara.GetCrystalLength();
00033
00034 SectorRmin1 = 489.27*mm;
00035 SectorRmax1 = 880.*mm;
00036 SectorRmin2 = 621.57*mm;
00037 SectorRmax2 = 1113.53*mm;
00038 SectorDz = WorldDz-44.*mm;
00039 SectorZPosition = -18.*mm;
00040
00041 for(G4int i=0;i<6;i++)
00042 cryNumInOneLayer[i] = emcPara.GetCryInOneLayer(i);
00043 for(G4int i=0;i<5;i++)
00044 pentaInOneSector[i] = emcPara.GetPentaInOneSector(i);
00045
00046 fTyvekThickness = emcPara.GetTyvekThickness();
00047 fAlThickness = emcPara.GetAlThickness();
00048 fMylarThickness = emcPara.GetMylarThickness();
00049 totalThickness=fTyvekThickness+fAlThickness+fMylarThickness;
00050
00051 G4String ParaPath = getenv("EMCSIMROOT");
00052 if(!ParaPath){
00053 G4Exception("BOOST environment not set!");
00054 }
00055 ParaPath += "/dat/EmcEndGeometry.dat";
00056
00057 ifstream fin;
00058 fin.open(ParaPath);
00059 assert(fin);
00060 for(G4int i=0;i<30;i++)
00061 for (G4int j=0;j<24;j++)
00062 fin>>param[i][j];
00063 for(G4int i=0;i<5;i++)
00064 for (G4int j=0;j<6;j++)
00065 fin>>penta[i][j];
00066 fin.close();
00067 }
00068
00069
00070 void BesEmcEndGeometry::ComputeParameters()
00071 {
00072
00074
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00092
00093 ReadParameters();
00094
00095 G4int pentaNb=0;
00096 for(G4int i=0;i<30;i++)
00097 {
00098 for (G4int j=0;j<8;j++)
00099 {
00100
00101 G4ThreeVector* pPnt = new G4ThreeVector(param[i][j],param[i][j+8],param[i][j+16]-WorldZPosition-SectorZPosition);
00102 fPnt[i][j] = *pPnt;
00103 }
00104
00105 if(i==5||i==6||i==14||i==15||i==16)
00106
00107 {
00108 for(G4int j=0;j<8;j++)
00109 fPnt[30+pentaNb][j] = fPnt[i][j];
00110
00111
00112 G4double y0,y1,y4,y5;
00113 G4ThreeVector v0,v1,v4,v5;
00114 y0 = penta[pentaNb][0];
00115 y1 = penta[pentaNb][1];
00116 y4 = penta[pentaNb][2];
00117 y5 = penta[pentaNb][3];
00118 v0 = (y0-fPnt[i][3].getY())*(fPnt[i][0]-fPnt[i][3])/(fPnt[i][0].getY()-fPnt[i][3].getY())
00119 +fPnt[i][3];
00120 v1 = (y1-fPnt[i][2].getY())*(fPnt[i][1]-fPnt[i][2])/(fPnt[i][1].getY()-fPnt[i][2].getY())
00121 +fPnt[i][2];
00122 v4 = (y4-fPnt[i][7].getY())*(fPnt[i][4]-fPnt[i][7])/(fPnt[i][4].getY()-fPnt[i][7].getY())
00123 +fPnt[i][7];
00124 v5 = (y5-fPnt[i][6].getY())*(fPnt[i][5]-fPnt[i][6])/(fPnt[i][5].getY()-fPnt[i][6].getY())
00125 +fPnt[i][6];
00126
00127 G4double x1,x5;
00128 x1 = penta[pentaNb][4];
00129 x5 = penta[pentaNb][5];
00130 v1 = (x1-v0.getX())*(v1-v0)/(v1.getX()-v0.getX())+v0;
00131 v5 = (x5-v4.getX())*(v5-v4)/(v5.getX()-v4.getX())+v4;
00132
00133 fPnt[i][0] = v0;
00134 fPnt[i][1] = v1;
00135 fPnt[i][4] = v4;
00136 fPnt[i][5] = v5;
00137
00138 fPnt[30+pentaNb][2] = v1;
00139 fPnt[30+pentaNb][3] = v0;
00140 fPnt[30+pentaNb][6] = v5;
00141 fPnt[30+pentaNb][7] = v4;
00142
00143 pentaNb++;
00144 }
00145 }
00146
00147
00148 G4ThreeVector temp[35][8];
00149 for(G4int i=0;i<35;i++)
00150 {
00151 for (G4int j=0;j<8;j++)
00152 {
00153 temp[i][j]=fPnt[i][j];
00154 fPnt[i][j].rotateZ(157.5*deg);
00155 fPnt[i][j].setX(-fPnt[i][j].getX());
00156 }
00157
00158
00159 for (G4int j=0;j<8;j++)
00160 {
00161 if(j<2)
00162 {
00163 G4ThreeVector v=fPnt[i][j];
00164 fPnt[i][j]=fPnt[i][3-j];
00165 fPnt[i][3-j]=v;
00166 }
00167 else if(j>=4&&j<6)
00168 {
00169 G4ThreeVector v=fPnt[i][j];
00170 fPnt[i][j]=fPnt[i][11-j];
00171 fPnt[i][11-j]=v;
00172 }
00173 }
00174 }
00175
00176
00177
00178
00179
00180
00181 Exchange(0,3); Exchange(1,2); Exchange(4,7); Exchange(5,31); Exchange(6,30);
00182 Exchange(8,12); Exchange(9,11); Exchange(13,17); Exchange(14,34); Exchange(15,33); Exchange(16,32);
00183 Exchange(18,23); Exchange(19,22); Exchange(20,21); Exchange(24,29); Exchange(25,28); Exchange(26,27);
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 for(G4int i=0;i<35;i++)
00195 {
00196 for (G4int j=0;j<8;j++)
00197 {
00198 G4ThreeVector pPnt1 = temp[i][j];
00199 fPnt1[i][j] = pPnt1.rotateZ(67.5*deg);
00200 }
00201 if((i==3)||(i==7)||(i==12)||(i==17)||(i==23)||(i==29))
00202 {
00203 fPnt1[i][0].setX(10);
00204 fPnt1[i][1].setX(10);
00205 fPnt1[i][4].setX(10);
00206 fPnt1[i][5].setX(10);
00207
00208 G4double y0 = fPnt1[i][0].getY()+10*(fPnt1[i][3].getY()-fPnt1[i][0].getY())/fPnt1[i][3].getX();
00209 G4double y1 = fPnt1[i][1].getY()+10*(fPnt1[i][2].getY()-fPnt1[i][1].getY())/fPnt1[i][2].getX();
00210 G4double y4 = fPnt1[i][4].getY()+10*(fPnt1[i][7].getY()-fPnt1[i][4].getY())/fPnt1[i][7].getX();
00211 G4double y5 = fPnt1[i][5].getY()+10*(fPnt1[i][6].getY()-fPnt1[i][5].getY())/fPnt1[i][6].getX();
00212
00213 G4double z0 = fPnt1[i][0].getZ()+10*(fPnt1[i][3].getZ()-fPnt1[i][0].getZ())/fPnt1[i][3].getX();
00214 G4double z1 = fPnt1[i][1].getZ()+10*(fPnt1[i][2].getZ()-fPnt1[i][1].getZ())/fPnt1[i][2].getX();
00215 G4double z4 = fPnt1[i][4].getZ()+10*(fPnt1[i][7].getZ()-fPnt1[i][4].getZ())/fPnt1[i][7].getX();
00216 G4double z5 = fPnt1[i][5].getZ()+10*(fPnt1[i][6].getZ()-fPnt1[i][5].getZ())/fPnt1[i][6].getX();
00217
00218 fPnt1[i][0].setY(y0);
00219 fPnt1[i][1].setY(y1);
00220 fPnt1[i][4].setY(y4);
00221 fPnt1[i][5].setY(y5);
00222
00223 fPnt1[i][0].setZ(z0);
00224 fPnt1[i][1].setZ(z1);
00225 fPnt1[i][4].setZ(z4);
00226 fPnt1[i][5].setZ(z5);
00227 }
00228 }
00229 }
00230
00231 void BesEmcEndGeometry::Exchange(G4int cry1, G4int cry2)
00232 {
00233 G4ThreeVector v;
00234 for(G4int i=0;i<8;i++)
00235 {
00236 v = fPnt[cry1][i];
00237 fPnt[cry1][i] = fPnt[cry2][i];
00238 fPnt[cry2][i] = v;
00239 }
00240 }
00241
00242 void BesEmcEndGeometry::ExchangeSector7(G4int cry1, G4int cry2)
00243 {
00244 G4ThreeVector v;
00245 for(G4int i=0;i<8;i++)
00246 {
00247 v = fPnt1[cry1][i];
00248 fPnt1[cry1][i] = fPnt1[cry2][i];
00249 fPnt1[cry2][i] = v;
00250 }
00251 }
00252
00253
00254 void BesEmcEndGeometry::ReflectX()
00255 {
00256 for(G4int i=0;i<35;i++)
00257 {
00258 for(G4int j=0;j<8;j++)
00259 {
00260 fPnt1[i][j].setX(-fPnt1[i][j].getX());
00261 }
00262
00263
00264 for (G4int j=0;j<8;j++)
00265 {
00266 if(j<2)
00267 {
00268 G4ThreeVector v=fPnt1[i][j];
00269 fPnt1[i][j]=fPnt1[i][3-j];
00270 fPnt1[i][3-j]=v;
00271 }
00272 else if(j>=4&&j<6)
00273 {
00274 G4ThreeVector v=fPnt1[i][j];
00275 fPnt1[i][j]=fPnt1[i][11-j];
00276 fPnt1[i][11-j]=v;
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 }
00292 ExchangeSector7(0,3); ExchangeSector7(1,2); ExchangeSector7(4,7);
00293 ExchangeSector7(5,31); ExchangeSector7(6,30); ExchangeSector7(8,12);
00294 ExchangeSector7(9,11); ExchangeSector7(13,17); ExchangeSector7(14,34);
00295 ExchangeSector7(15,33); ExchangeSector7(16,32); ExchangeSector7(18,23);
00296 ExchangeSector7(19,22); ExchangeSector7(20,21); ExchangeSector7(24,29);
00297 ExchangeSector7(25,28); ExchangeSector7(26,27);
00298 }
00299
00300 void BesEmcEndGeometry::Zoom(const G4ThreeVector pos[8], const G4double factor)
00301 {
00302 G4ThreeVector center1(0,0,0);
00303 G4ThreeVector center2(0,0,0);
00304 for(G4int i=0;i<8;i++)
00305 zoomPoint[i]=0;
00306
00307 for(G4int i=0;i<8;i++)
00308 {
00309 if(i<4) center1+=pos[i];
00310 else center2+=pos[i];
00311 }
00312 center1/=4;
00313 center2/=4;
00314
00315 for(G4int i=0;i<8;i++)
00316 {
00317 if(i<4) zoomPoint[i]=factor*pos[i]+(1-factor)*center1;
00318 else zoomPoint[i]=factor*pos[i]+(1-factor)*center2;
00319 }
00320 }
00321
00322
00323 void BesEmcEndGeometry::ModifyForCasing(G4ThreeVector pos[8], G4int CryNb)
00324 {
00325 G4ThreeVector center1=0;
00326 G4ThreeVector center2=0;
00327
00328 const G4double dt=1e-5;
00329
00330 if(CryNb==5||CryNb==6||CryNb==14||CryNb==15||CryNb==16)
00331 {
00332 center1 = (pos[0]+pos[1])*(1-dt)/2+(pos[2]+pos[3])*dt/2;
00333 center2 = (pos[4]+pos[5])*(1-dt)/2+(pos[6]+pos[7])*dt/2;
00334 }
00335 else if(CryNb>=30&&CryNb<35)
00336 {
00337 center1 = (pos[0]+pos[1])*dt/2+(pos[2]+pos[3])*(1-dt)/2;
00338 center2 = (pos[4]+pos[5])*dt/2+(pos[6]+pos[7])*(1-dt)/2;
00339 }
00340 else
00341 {
00342 center1 = (pos[0]+pos[1]+pos[2]+pos[3])/4;
00343 center2 = (pos[4]+pos[5]+pos[6]+pos[7])/4;
00344 }
00345
00346 G4double r1=(pos[1]-center1).r();
00347 G4double r2=(pos[2]-center1).r();
00348 G4double r12=(pos[1]-pos[2]).r();
00349 G4double theta=acos((r2*r2+r12*r12-r1*r1)/(2*r2*r12));
00350 G4double h=r2*sin(theta);
00351 G4double t1=totalThickness/h;
00352
00353 r1=(pos[5]-center2).r();
00354 r2=(pos[6]-center2).r();
00355 r12=(pos[5]-pos[6]).r();
00356 theta=acos((r2*r2+r12*r12-r1*r1)/(2*r2*r12));
00357 h=r2*sin(theta);
00358 G4double t2=totalThickness/h;
00359
00360 for(G4int i=0;i<8;i++)
00361 {
00362 if(i<4)
00363 {
00364 cryPoint[i] = (1-t1)*pos[i]+t1*center1;
00365 }
00366 else
00367 {
00368 G4ThreeVector temp = (1-t2)*pos[i]+t2*center2;
00369 cryPoint[i] = (1-totalThickness/CrystalLength)*temp+(totalThickness/CrystalLength)*pos[i-4];
00370 }
00371
00372 }
00373 }
00374
00375 G4ThreeVector BesEmcEndGeometry::ComputeDimAndPos
00376 (const G4int partId, const G4int numTheta, const G4int numPhi)
00377 {
00378
00379 G4int sector=-1, cryNb=-1;
00380 G4int leftFlag=0;
00381 G4int downFlag=0;
00382 G4int pentaFlag=0;
00383 G4int flag=0;
00384 G4double A1=0,a1=0,B1=0,b1=0,C1=0,c1=0,D1=0,d1=0,E1=0,e1=0;
00385 G4int m_numPhi=0;
00386 G4ThreeVector position=0;
00387 G4int cryInOneSector = cryNumInOneLayer[numTheta]/16;
00388 G4ThreeVector pos[8];
00389
00390 if(partId==2)
00391 {
00392 if(numPhi>=0&&numPhi<8*cryInOneSector)
00393 m_numPhi=8*cryInOneSector-1-numPhi;
00394 else if(numPhi>=8*cryInOneSector&&numPhi<16*cryInOneSector)
00395 m_numPhi=16*cryInOneSector-1-numPhi;
00396 }
00397 else
00398 m_numPhi=numPhi;
00399
00400 if(numPhi>=4*cryInOneSector&&numPhi<5*cryInOneSector)
00401 {
00402 leftFlag = 1;
00403 m_numPhi=8*cryInOneSector-1-numPhi;
00404 }
00405 else if(numPhi>=11*cryInOneSector&&numPhi<12*cryInOneSector)
00406 {
00407 leftFlag = 1;
00408 downFlag = 1;
00409 m_numPhi=numPhi-8*cryInOneSector;
00410 }
00411 if(numPhi>=12*cryInOneSector&&numPhi<13*cryInOneSector)
00412 {
00413 downFlag = 1;
00414 m_numPhi=16*cryInOneSector-1-numPhi;
00415 }
00416
00417
00418 G4int cryNbOffset = 0;
00419 for(G4int i=0;i<numTheta;i++)
00420 cryNbOffset += cryNumInOneLayer[i]/16;
00421 if(cryInOneSector)
00422 sector = m_numPhi/cryInOneSector;
00423 cryNb = m_numPhi-cryInOneSector*sector+cryNbOffset;
00424 sector += 3;
00425 if(sector>15&§or<=18)
00426 sector -= 16;
00427
00428
00429 if(sector==6)
00430 for(G4int i=0;i<8;i++)
00431 pos[i]=fPnt1[cryNb][i];
00432 else
00433 for(G4int i=0;i<8;i++)
00434 {
00435 pos[i]=fPnt[cryNb][i];
00436 pos[i].rotateZ(-67.5*deg+sector*22.5*deg);
00437 }
00438
00439
00440 Zoom(pos,0.999);
00441 ModifyForCasing(zoomPoint,cryNb);
00442 G4double A = (cryPoint[0]-cryPoint[3]).r();
00443 G4double a = (cryPoint[4]-cryPoint[7]).r();
00444 G4double B = (cryPoint[1]-cryPoint[2]).r();
00445 G4double b = (cryPoint[5]-cryPoint[6]).r();
00446 G4double C = (cryPoint[0]-cryPoint[1]).r();
00447 G4double c = (cryPoint[4]-cryPoint[5]).r();
00448 G4double D = (cryPoint[2]-cryPoint[3]).r();
00449 G4double d = (cryPoint[6]-cryPoint[7]).r();
00450
00451
00452 for(G4int i=0;i<8;i++)
00453 {
00454 pos[i].setZ(pos[i].getZ()+WorldZPosition+SectorZPosition);
00455 if(leftFlag==1)
00456 pos[i].setX(-pos[i].getX());
00457 if(downFlag==1)
00458 pos[i].setY(-pos[i].getY());
00459 if(partId==2)
00460 {
00461 pos[i].setX(-pos[i].getX());
00462 pos[i].setZ(-pos[i].getZ());
00463 }
00464 }
00465
00466
00467 for(G4int j=4;j<8;j++)
00468 position += pos[j];
00469 position /= 4;
00470
00471
00472 for(G4int i=0;i<5;i++)
00473 {
00474 if(cryNb==pentaInOneSector[i])
00475 {
00476 pentaFlag = 1;
00477 G4ThreeVector penta[8];
00478
00479
00480 if(sector==6)
00481 for(G4int j=0;j<8;j++)
00482 penta[j]=fPnt1[30+i][j];
00483 else
00484 for(G4int j=0;j<8;j++)
00485 {
00486 penta[j]=fPnt[30+i][j];
00487 penta[j].rotateZ(-67.5*deg+sector*22.5*deg);
00488 }
00489
00490
00491 ModifyForCasing(penta,30+i);
00492 A1 = (cryPoint[1]-cryPoint[2]).r();
00493 a1 = (cryPoint[5]-cryPoint[6]).r();
00494 B1 = (cryPoint[1]-cryPoint[0]).r();
00495 b1 = (cryPoint[5]-cryPoint[4]).r();
00496 C1 = (cryPoint[0]-cryPoint[3]).r()+A;
00497 c1 = (cryPoint[4]-cryPoint[7]).r()+a;
00498 D1 = D;
00499 d1 = d;
00500 E1 = B;
00501 e1 = b;
00502
00503
00504 for(G4int j=0;j<8;j++)
00505 {
00506 penta[j].setZ(penta[j].getZ()+WorldZPosition+SectorZPosition);
00507 if(leftFlag==1)
00508 penta[j].setX(-penta[j].getX());
00509 if(downFlag==1)
00510 penta[j].setY(-penta[j].getY());
00511 if(partId==2)
00512 {
00513 penta[j].setX(-penta[j].getX());
00514 penta[j].setZ(-penta[j].getZ());
00515 }
00516 }
00517
00518
00519 for(G4int j=4;j<8;j++)
00520 {
00521 if(j!=0&&j!=4)
00522 position += pos[j];
00523 if(j==0||j==1||j==4||j==5)
00524 position += penta[j];
00525 }
00526 position /= 10;
00527
00528 flag = leftFlag+downFlag;
00529 if(flag==1)
00530 {
00531 G4double temp1 = B1; B1 = D1; D1 = temp1;
00532 temp1 = A1; A1 = E1; E1 = temp1;
00533 temp1 = b1; b1 = d1; d1 = temp1;
00534 temp1 = a1; a1 = e1; e1 = temp1;
00535 }
00536
00537 break;
00538 }
00539 }
00540
00541 flag = leftFlag+downFlag+partId/2;
00542 if(flag==1||flag==3)
00543 {
00544 G4double temp = C; C = D; D = temp;
00545 temp = c; c = d; d = temp;
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 return position;
00563 }