00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00158
00159
00160
00161
00162 #include "StChain.h"
00163 #include "StTpcDb.h"
00164 #include "tables/St_trgTimeOffset_Table.h"
00165 #include "tables/St_dst_L0_Trigger_Table.h"
00166 #include "TUnixTime.h"
00167 #include "StMessMgr.h"
00168 #include "St_db_Maker/St_db_Maker.h"
00169 #include "TVector3.h"
00170 #include "TGeoManager.h"
00171 #include "StDetectorDbMaker/StTpcSurveyC.h"
00172 StTpcDb* gStTpcDb = 0;
00173
00174
00175 ClassImp(StTpcDb);
00176
00177 StTpcDb::StTpcDb() {
00178 assert(gStTpcDb==0);
00179 memset(mBeg,0,mEnd-mBeg+1);
00180 mTpc2GlobMatrix = new TGeoHMatrix("Default Tpc2Glob");
00181 for (Int_t i = 1; i <= 24; i++) {
00182 for (Int_t k = 0; k < kTotalTpcSectorRotaions; k++) {
00183 mTpcSectorRotations[i-1][k] = new TGeoHMatrix(Form("Default %02i %i",i,k));
00184 }
00185 }
00186 mFlip = new TGeoHMatrix;
00187 Double_t DriftDistance = Dimensions()->gatingGridZ();
00188 Double_t Rotation[9] = {0, 1, 0,
00189 1, 0, 0,
00190 0, 0,-1};
00191 Double_t Translation[3] = {0, 0, DriftDistance};
00192 mFlip->SetName("Flip"); mFlip->SetRotation(Rotation); mFlip->SetTranslation(Translation);
00193 gStTpcDb = this;
00194 }
00195
00196
00197 StTpcDb::~StTpcDb() {
00198 for (Int_t i = 0;i<24;i++) {
00199 for (Int_t k = 0; k < kTotalTpcSectorRotaions; k++)
00200 SafeDelete(mTpcSectorRotations[i][k]);
00201 }
00202 SafeDelete(mExB);
00203 SafeDelete(mTpc2GlobMatrix);
00204 SafeDelete(mFlip);
00205 gStTpcDb = 0;
00206 }
00207
00208 float StTpcDb::DriftVelocity(Int_t sector) {
00209 static UInt_t u2007 = TUnixTime(20070101,0,1).GetUTime();
00210 assert(mUc > 0);
00211 if (mUc < u2007) sector = 24;
00212 UInt_t kase = 1;
00213 if (sector <= 12) kase = 0;
00214 return 1e6*mDriftVel[kase];
00215 }
00216
00217 void StTpcDb::SetDriftVelocity() {
00218 static UInt_t u0 = 0;
00219 static UInt_t u1 = 0;
00220 static UInt_t umax = TUnixTime(20250101,0,1).GetUTime();
00221
00222 static St_tpcDriftVelocity *dvel0 = 0;
00223 static St_tpcDriftVelocity *dvel1 = 0;
00224 static TDatime t[2];
00225 UInt_t uc = TUnixTime(StMaker::GetChain()->GetDateTime(),1).GetUTime();
00226 if (uc != mUc) {
00227 if (! dvel0 || (uc < umax && ((uc < u0) || (uc > u1)))) {
00228 dvel0 = (St_tpcDriftVelocity *) StMaker::GetChain()->GetDataBase("Calibrations/tpc/tpcDriftVelocity");
00229 if (! dvel0) {
00230 gMessMgr->Message("StTpcDb::Error Finding Tpc DriftVelocity","E");
00231 mUc = 0;
00232 return;
00233 }
00234 if (St_db_Maker::GetValidity(dvel0,t) < 0) {
00235 gMessMgr->Message("StTpcDb::Error Wrong Validity Tpc DriftVelocity","E");
00236 mUc = 0;
00237 return;
00238 }
00239 u0 = TUnixTime(t[0],1).GetUTime();
00240 u1 = TUnixTime(t[1],1).GetUTime();
00241 SafeDelete(dvel1);
00242 if (u1 < umax && u1 - u0 < 7*24*3600)
00243 dvel1 = (St_tpcDriftVelocity *) StMaker::GetChain()->GetDataBase("Calibrations/tpc/tpcDriftVelocity",&t[1]);
00244 }
00245
00246 if (!(u0<=uc && uc<u1)) {
00247
00248 SafeDelete(dvel1);
00249 if (u1 < umax && u1 - u0 < 7*24*3600 && uc - u0 < 7*24*3600) {
00250 dvel1 = (St_tpcDriftVelocity *) StMaker::GetChain()->GetDataBase("Calibrations/tpc/tpcDriftVelocity",&t[1]);
00251 if (! dvel1) {
00252 gMessMgr->Message("StTpcDb::Error Finding next Tpc DriftVelocity","W");
00253 }
00254 }
00255 }
00256
00257 mDriftVel[0] = mDriftVel[1] = 0;
00258 tpcDriftVelocity_st *d0 = dvel0->GetTable();
00259 if (dvel1) {
00260 tpcDriftVelocity_st *d1 = dvel1->GetTable();
00261 if (d0->laserDriftVelocityWest > 0 && d1->laserDriftVelocityWest > 0)
00262 mDriftVel[0] = (d1->laserDriftVelocityWest *(uc-u0) + d0->laserDriftVelocityWest *(u1-uc))/(u1 - u0);
00263 if (d0->laserDriftVelocityEast > 0 && d1->laserDriftVelocityEast > 0)
00264 mDriftVel[1] = (d1->laserDriftVelocityEast *(uc-u0) + d0->laserDriftVelocityEast *(u1-uc))/(u1 - u0);
00265 if (mDriftVel[0] <= 0.0 || mDriftVel[1] <= 0.0) {
00266 if (d0->cathodeDriftVelocityWest > 0 && d1->cathodeDriftVelocityWest > 0)
00267 mDriftVel[0] = (d1->cathodeDriftVelocityWest*(uc-u0) + d0->cathodeDriftVelocityWest*(u1-uc))/(u1 - u0);
00268 if (d0->cathodeDriftVelocityEast > 0 && d1->cathodeDriftVelocityEast > 0)
00269 mDriftVel[1] = (d1->cathodeDriftVelocityEast*(uc-u0) + d0->cathodeDriftVelocityEast*(u1-uc))/(u1 - u0);
00270 }
00271 }
00272 if (mDriftVel[0] <= 0.0 || mDriftVel[1] <= 0.0) {
00273 mDriftVel[0] = d0->laserDriftVelocityWest;
00274 mDriftVel[1] = d0->laserDriftVelocityEast;
00275 if (mDriftVel[0] <= 0.0) mDriftVel[0] = d0->cathodeDriftVelocityWest;
00276 if (mDriftVel[1] <= 0.0) mDriftVel[1] = d0->cathodeDriftVelocityEast;
00277 }
00278 #if 0
00279 LOG_INFO << "Set Tpc Drift Velocity =" << mDriftVel[0] << " (West) " << mDriftVel[0] << " (East) for "
00280 << StMaker::GetChain()->GetDateTime().AsString() << endm;
00281 #endif
00282 mUc = uc;
00283 }
00284 }
00285
00286 void StTpcDb::SetTpcRotations() {
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 TGeoTranslation T123(0,123,0); T123.SetName("T123"); if (Debug() > 1) T123.Print();
00302 assert(Dimensions()->numberOfSectors() == 24);
00303 Double_t phi, theta, psi;
00304 #define __NEW__SCHEMA_FOR_ROTATION__
00305 #ifndef __NEW__SCHEMA_FOR_ROTATION__
00306 Double_t s, offset;
00307 #endif
00308 Int_t iphi;
00309 TGeoRotation *rotm = 0;
00310 TObjArray *listOfMatrices = 0;
00311 TString Rot;
00312 for (Int_t sector = 0; sector <= 24; sector++) {
00313 Int_t k;
00314 Int_t k1 = kSupS2Tpc;
00315 Int_t k2 = kTotalTpcSectorRotaions;
00316 if (sector == 0) {k2 = k1; k1 = kUndefSector;}
00317 for (k = k1; k < k2; k++) {
00318 Int_t Id = 0;
00319 TGeoHMatrix rotA;
00320 if (!sector ) {
00321 St_tpcGlobalPositionC *tpcGlobalPosition = St_tpcGlobalPositionC::instance();
00322 assert(tpcGlobalPosition);
00323 Id = 1;
00324 phi = 0.0;
00325 theta = tpcGlobalPosition->PhiXZ_geom()*TMath::RadToDeg();
00326 psi = tpcGlobalPosition->PhiYZ_geom()*TMath::RadToDeg();
00327 rotA.RotateX(-psi);
00328 rotA.RotateY(-theta);
00329 rotA.RotateZ(-phi);
00330 Double_t transTpcRefSys[3] = {tpcGlobalPosition->LocalxShift(),
00331 tpcGlobalPosition->LocalyShift(),
00332 tpcGlobalPosition->LocalzShift()};
00333 rotA.SetTranslation(transTpcRefSys);
00334 } else {
00335 Id = 10*sector + k;
00336 TGeoTranslation TIO;
00337 TGeoRotation RIO;
00338 switch (k) {
00339 case kSupS2Tpc:
00340 if (sector <= 12) {iphi = (360 + 90 - 30* sector )%360; Rot = Form("R%03i",iphi);}
00341 else {iphi = ( 90 + 30*(sector - 12))%360; Rot = Form("Y%03i",iphi);}
00342 rotm = 0;
00343 if (gGeoManager) {
00344 listOfMatrices = gGeoManager->GetListOfMatrices();
00345 rotm = (TGeoRotation *) listOfMatrices->FindObject(Rot);
00346 }
00347 if (! rotm) {
00348 if (sector <= 12) rotm = new TGeoRotation(Rot);
00349 else rotm = new TGeoRotation(Rot, 90.0, 0.0, 90.0, -90.0, 180.0, 0.00);
00350 rotm->RotateZ(iphi);
00351 }
00352 rotA = *rotm;
00353 #ifdef __NEW__SCHEMA_FOR_ROTATION__
00354 rotA *= StTpcSuperSectorPosition::instance()->GetMatrix(sector-1);
00355 #endif
00356 if (gGeoManager) rotm->RegisterYourself();
00357 else SafeDelete(rotm);
00358 break;
00359 case kSupS2Glob:
00360 rotA = Tpc2GlobalMatrix() * SupS2Tpc(sector);
00361 break;
00362 #ifdef __NEW__SCHEMA_FOR_ROTATION__
00363 case kSubSInner2SupS: rotA = Flip(); break;
00364 case kSubSOuter2SupS: rotA = Flip() * StTpcOuterSectorPosition::instance()->GetMatrix(sector-1); break;
00365 #else
00366 case kSubSInner2SupS:
00367 case kSubSOuter2SupS:
00368 s = -1;
00369 if (sector > 12) s = +1;
00370 if (k == kSubSInner2SupS) {
00371 offset = s*St_tpcSectorPositionC::instance()->innerPositionOffsetX(sector-1);
00372 phi = s*St_tpcSectorPositionC::instance()->innerRotation(sector-1);
00373 } else {
00374 offset = s*St_tpcSectorPositionC::instance()->outerPositionOffsetX(sector-1);
00375 phi = s*St_tpcSectorPositionC::instance()->outerRotation(sector-1);
00376 }
00377 TIO.SetTranslation(-offset, -123, 0); if (Debug() > 1) TIO.Print();
00378 RIO.SetAngles(-phi,0,0); if (Debug() > 1) RIO.Print();
00379 rotA = T123 * RIO * TIO;
00380 if (k != kSubSInner2SupS)
00381 rotA *= StTpcOuterSectorPosition::instance()->GetMatrix(sector-1);
00382
00383 #endif
00384 break;
00385 case kSubSInner2Tpc: rotA = SupS2Tpc(sector) * SubSInner2SupS(sector); break;
00386 case kSubSOuter2Tpc: rotA = SupS2Tpc(sector) * SubSOuter2SupS(sector); break;
00387
00388 case kSubSInner2Glob: rotA = Tpc2GlobalMatrix() * SubSInner2Tpc(sector); break;
00389 case kSubSOuter2Glob: rotA = Tpc2GlobalMatrix() * SubSOuter2Tpc(sector); break;
00390
00391 #ifdef __NEW__SCHEMA_FOR_ROTATION__
00392 case kPadInner2SupS: rotA = SubSInner2SupS(sector); break;
00393 case kPadOuter2SupS: rotA = SubSOuter2SupS(sector); break;
00394 #else
00395 case kPadInner2SupS: rotA = Flip()*SubSInner2SupS(sector); break;
00396 case kPadOuter2SupS: rotA = Flip()*SubSOuter2SupS(sector); break;
00397 #endif
00398 case kPadInner2Tpc: rotA = SupS2Tpc(sector) * PadInner2SupS(sector); break;
00399 case kPadOuter2Tpc: rotA = SupS2Tpc(sector) * PadOuter2SupS(sector); break;
00400
00401 case kPadInner2Glob: rotA = Tpc2GlobalMatrix() * PadInner2Tpc(sector); break;
00402 case kPadOuter2Glob: rotA = Tpc2GlobalMatrix() * PadOuter2Tpc(sector); break;
00403 default:
00404 assert(0);
00405 }
00406 }
00407
00408 Double_t *r = rotA.GetRotationMatrix();
00409 Double_t norm;
00410 TVector3 d(r[0],r[3],r[6]); norm = 1/d.Mag(); d *= norm;
00411 TVector3 t(r[2],r[5],r[8]); norm = 1/t.Mag(); t *= norm;
00412 TVector3 n(r[1],r[4],r[7]);
00413 TVector3 c = d.Cross(t);
00414 if (c.Dot(n) < 0) c *= -1;
00415 Double_t rot[9] = {
00416 d[0], c[0], t[0],
00417 d[1], c[1], t[1],
00418 d[2], c[2], t[2]};
00419 rotA.SetRotation(rot);
00420 const Char_t *names[kTotalTpcSectorRotaions] = {
00421 "SupS_%02itoTpc",
00422 "SupS_%02itoGlob",
00423 "SubS_%02iInner2SupS",
00424 "SubS_%02iOuter2SupS",
00425 "SubS_%02iInner2Tpc",
00426 "SubS_%02iOuter2Tpc",
00427 "SubS_%02iInner2Glob",
00428 "SubS_%02iOuter2Glob",
00429 "PadInner2SupS_%02i",
00430 "PadOuter2SupS_%02i",
00431 "SupS_%02i12Inner2Tpc",
00432 "SupS_%02i12Outer2Tpc",
00433 "SupS_%02i12Inner2Glob",
00434 "SupS_%02i12Outer2Glob"
00435 };
00436 if (sector == 0) rotA.SetName("Tpc2Glob");
00437 else rotA.SetName(Form(names[k],sector));
00438 if (Debug() > 1) {
00439 cout << "Id : " << Id << " "; rotA.Print();
00440 }
00441 SetTpcRotationMatrix(&rotA,sector,k);
00442 }
00443 }
00444 #undef __NEW__SCHEMA_FOR_ROTATION__
00445 }