187 #include "tables/St_trgTimeOffset_Table.h"
188 #include "tables/St_dst_L0_Trigger_Table.h"
189 #include "TUnixTime.h"
190 #include "StMessMgr.h"
191 #include "St_db_Maker/St_db_Maker.h"
192 #include "TVector3.h"
193 #include "TGeoManager.h"
194 #include "StDetectorDbMaker/StTpcSurveyC.h"
195 #include "StDetectorDbMaker/St_tpcDriftVelocityC.h"
196 #include "StDetectorDbMaker/St_TpcDriftVelRowCorC.h"
197 #include "StarMagField.h"
200 Bool_t StTpcDb::mOldScheme = kTRUE;
207 memset(mBeg,0,mEnd-mBeg+1);
208 mTpc2GlobMatrix =
new TGeoHMatrix(
"Default Tpc2Glob");
209 for (Int_t i = 1; i <= 24; i++) {
210 for (Int_t k = 0; k < kTotalTpcSectorRotaions; k++) {
211 mTpcSectorRotations[i-1][k] =
new TGeoHMatrix(Form(
"Default %02i %i",i,k));
214 mFlip =
new TGeoHMatrix;
215 mzGG = Dimensions()->gatingGridZ();
216 Double_t Rotation[9] = {0, 1, 0,
220 mFlip->SetName(
"Flip"); mFlip->SetRotation(Rotation);
221 mShift[0] =
new TGeoTranslation(
"Signed Drift distance to z for East", 0, 0, -mzGG);
222 mShift[1] =
new TGeoTranslation(
"Signed Drift distance to z for West", 0, 0, mzGG);
223 mHalf[0] =
new TGeoHMatrix(
"Default for east part of TPC");
224 mHalf[1] =
new TGeoHMatrix(
"Default for west part of TPC");
229 StTpcDb::~StTpcDb() {
230 for (Int_t i = 0;i<24;i++) {
231 for (Int_t k = 0; k < kTotalTpcSectorRotaions; k++)
232 SafeDelete(mTpcSectorRotations[i][k]);
234 SafeDelete(mHalf[0]);
235 SafeDelete(mHalf[1]);
236 SafeDelete(mShift[0]);
237 SafeDelete(mShift[1]);
238 SafeDelete(mTpc2GlobMatrix);
243 float StTpcDb::DriftVelocity(Int_t sector, Int_t row) {
244 static UInt_t u2007 =
TUnixTime(20070101,0,1).GetUTime();
246 if (mUc < u2007) sector = 24;
248 if (sector <= 12) kase = 0;
249 Float_t DV =1e6*mDriftVel[kase];
252 if (St_TpcDriftVelRowCorC::instance()->idx()) {
253 DV *= (1. - St_TpcDriftVelRowCorC::instance()->CalcCorrection(0,row));
259 void StTpcDb::SetDriftVelocity() {
260 static UInt_t u0 = 0;
261 static UInt_t u1 = 0;
262 static UInt_t umax =
TUnixTime(20250101,0,1).GetUTime();
264 static St_tpcDriftVelocity *dvel0 = 0;
265 static St_tpcDriftVelocity *dvel1 = 0;
267 UInt_t uc =
TUnixTime(StMaker::GetChain()->GetDateTime(),1).GetUTime();
269 if (! dvel0 || (uc < umax && ((uc < u0) || (uc > u1)))) {
270 dvel0 = (St_tpcDriftVelocity *) St_tpcDriftVelocityC::instance()->Table();
272 gMessMgr->Message(
"StTpcDb::Error Finding Tpc DriftVelocity",
"E");
276 if (St_db_Maker::GetValidity(dvel0,t) < 0) {
277 gMessMgr->Message(
"StTpcDb::Error Wrong Validity Tpc DriftVelocity",
"E");
284 if (u1 < umax && u1 - u0 < 7*24*3600)
285 dvel1 = (St_tpcDriftVelocity *) StMaker::GetChain()->GetDataBase(
"Calibrations/tpc/tpcDriftVelocity",&t[1]);
288 if (!(u0<=uc && uc<u1)) {
291 if (u1 < umax && u1 - u0 < 7*24*3600 && uc - u0 < 7*24*3600) {
292 dvel1 = (St_tpcDriftVelocity *) StMaker::GetChain()->GetDataBase(
"Calibrations/tpc/tpcDriftVelocity",&t[1]);
294 gMessMgr->Message(
"StTpcDb::Error Finding next Tpc DriftVelocity",
"W");
299 mDriftVel[0] = mDriftVel[1] = 0;
300 tpcDriftVelocity_st *d0 = dvel0->GetTable();
302 tpcDriftVelocity_st *d1 = dvel1->GetTable();
303 if (d0->laserDriftVelocityWest > 0 && d1->laserDriftVelocityWest > 0)
304 mDriftVel[0] = (d1->laserDriftVelocityWest *(uc-u0) + d0->laserDriftVelocityWest *(u1-uc))/(u1 - u0);
305 if (d0->laserDriftVelocityEast > 0 && d1->laserDriftVelocityEast > 0)
306 mDriftVel[1] = (d1->laserDriftVelocityEast *(uc-u0) + d0->laserDriftVelocityEast *(u1-uc))/(u1 - u0);
307 if (mDriftVel[0] <= 0.0 || mDriftVel[1] <= 0.0) {
308 if (d0->cathodeDriftVelocityWest > 0 && d1->cathodeDriftVelocityWest > 0)
309 mDriftVel[0] = (d1->cathodeDriftVelocityWest*(uc-u0) + d0->cathodeDriftVelocityWest*(u1-uc))/(u1 - u0);
310 if (d0->cathodeDriftVelocityEast > 0 && d1->cathodeDriftVelocityEast > 0)
311 mDriftVel[1] = (d1->cathodeDriftVelocityEast*(uc-u0) + d0->cathodeDriftVelocityEast*(u1-uc))/(u1 - u0);
314 if (mDriftVel[0] <= 0.0 || mDriftVel[1] <= 0.0) {
315 mDriftVel[0] = d0->laserDriftVelocityWest;
316 mDriftVel[1] = d0->laserDriftVelocityEast;
317 if (mDriftVel[0] <= 0.0) mDriftVel[0] = d0->cathodeDriftVelocityWest;
318 if (mDriftVel[1] <= 0.0) mDriftVel[1] = d0->cathodeDriftVelocityEast;
321 LOG_INFO <<
"Set Tpc Drift Velocity =" << mDriftVel[0] <<
" (West) " << mDriftVel[0] <<
" (East) for "
322 << StMaker::GetChain()->GetDateTime().AsString() << endm;
328 void StTpcDb::SetTpcRotations() {
380 assert(Dimensions()->numberOfSectors() == 24);
381 Float_t gFactor = StarMagField::Instance()->GetFactor();
382 Double_t phi, theta, psi;
384 TGeoRotation *rotm = 0;
385 TObjArray *listOfMatrices = 0;
387 if (gEnv->GetValue(
"NewTpcAlignment",0) != 0) mOldScheme = kFALSE;
389 LOG_INFO <<
"StTpcDb::SetTpcRotations use new schema for Rotation matrices" << endm;
391 LOG_INFO <<
"StTpcDb::SetTpcRotations use old schema for Rotation matrices" << endm;
394 for (Int_t sector = 0; sector <= 24; sector++) {
396 Int_t k1 = kSupS2Tpc;
397 Int_t k2 = kTotalTpcSectorRotaions;
398 if (sector == 0) {k2 = k1; k1 = kUndefSector;}
399 for (k = k1; k < k2; k++) {
406 assert(tpcGlobalPosition);
409 theta = tpcGlobalPosition->PhiXZ_geom()*TMath::RadToDeg();
410 psi = tpcGlobalPosition->PhiYZ_geom()*TMath::RadToDeg();
412 rotA.RotateY(-theta);
414 Double_t transTpcRefSys[3] = {tpcGlobalPosition->LocalxShift(),
415 tpcGlobalPosition->LocalyShift(),
416 tpcGlobalPosition->LocalzShift()};
417 rotA.SetTranslation(transTpcRefSys);
419 rotA = StTpcPosition::instance()->GetMatrix();
420 *mHalf[east] = StTpcHalfPosition::instance()->GetEastMatrix();
421 *mHalf[west] = StTpcHalfPosition::instance()->GetWestMatrix();
425 StBeamDirection part = east;
426 if (sector <= 12) part = west;
429 if (sector <= 12) {iphi = (360 + 90 - 30* sector )%360; Rot = Form(
"R%03i",iphi);}
430 else {iphi = ( 90 + 30*(sector - 12))%360; Rot = Form(
"Y%03i",iphi);}
433 listOfMatrices = gGeoManager->GetListOfMatrices();
434 rotm = (TGeoRotation *) listOfMatrices->FindObject(Rot);
437 if (sector <= 12) rotm =
new TGeoRotation(Rot);
438 else rotm =
new TGeoRotation(Rot, 90.0, 0.0, 90.0, -90.0, 180.0, 0.00);
441 rotA = (*mShift[part]) * (*mHalf[part]) * (*rotm);
442 rotA *= StTpcSuperSectorPosition::instance()->GetMatrix(sector-1);
443 if (gGeoManager) rotm->RegisterYourself();
444 else SafeDelete(rotm);
447 rotA = Tpc2GlobalMatrix() * SupS2Tpc(sector);
449 case kSubSInner2SupS:
450 if (mOldScheme) {rotA = Flip();
break;}
451 chair = StTpcInnerSectorPosition::instance();
452 case kSubSOuter2SupS:
453 if (mOldScheme) {rotA = Flip() * StTpcOuterSectorPosition::instance()->GetMatrix(sector-1);
break;}
454 if (! chair) chair = StTpcOuterSectorPosition::instance();
455 rotA = Flip() * chair->GetMatrix(sector-1);
456 if (chair->GetNRows() > 24) {
458 rotA *= chair->GetMatrix(sector-1+24);
459 }
else if (gFactor < -0.2) {
460 rotA *= chair->GetMatrix(sector-1+24).Inverse();
464 case kSubSInner2Tpc: rotA = SupS2Tpc(sector) * SubSInner2SupS(sector);
break;
465 case kSubSOuter2Tpc: rotA = SupS2Tpc(sector) * SubSOuter2SupS(sector);
break;
467 case kSubSInner2Glob: rotA = Tpc2GlobalMatrix() * SubSInner2Tpc(sector);
break;
468 case kSubSOuter2Glob: rotA = Tpc2GlobalMatrix() * SubSOuter2Tpc(sector);
break;
470 case kPadInner2SupS: rotA = SubSInner2SupS(sector);
break;
471 case kPadOuter2SupS: rotA = SubSOuter2SupS(sector);
break;
472 case kPadInner2Tpc: rotA = SupS2Tpc(sector) * PadInner2SupS(sector);
break;
473 case kPadOuter2Tpc: rotA = SupS2Tpc(sector) * PadOuter2SupS(sector);
break;
475 case kPadInner2Glob: rotA = Tpc2GlobalMatrix() * PadInner2Tpc(sector);
break;
476 case kPadOuter2Glob: rotA = Tpc2GlobalMatrix() * PadOuter2Tpc(sector);
break;
482 Double_t *r = rotA.GetRotationMatrix();
484 TVector3 d(r[0],r[3],r[6]); norm = 1/d.Mag(); d *= norm;
485 TVector3 t(r[2],r[5],r[8]); norm = 1/t.Mag(); t *= norm;
486 TVector3 n(r[1],r[4],r[7]);
487 TVector3 c = d.Cross(t);
488 if (c.Dot(n) < 0) c *= -1;
493 rotA.SetRotation(rot);
494 const Char_t *names[kTotalTpcSectorRotaions] = {
497 "SubS_%02iInner2SupS",
498 "SubS_%02iOuter2SupS",
499 "SubS_%02iInner2Tpc",
500 "SubS_%02iOuter2Tpc",
501 "SubS_%02iInner2Glob",
502 "SubS_%02iOuter2Glob",
503 "PadInner2SupS_%02i",
504 "PadOuter2SupS_%02i",
505 "SupS_%02i12Inner2Tpc",
506 "SupS_%02i12Outer2Tpc",
507 "SupS_%02i12Inner2Glob",
508 "SupS_%02i12Outer2Glob"
510 if (sector == 0) rotA.SetName(
"Tpc2Glob");
511 else rotA.SetName(Form(names[k],sector));
513 cout <<
"Id : " << Id <<
" "; rotA.Print();
515 SetTpcRotationMatrix(&rotA,sector,k);