255 #include "StTpcCoordinateTransform.hh"
256 #include "StMatrix.hh"
258 #include "StMessMgr.h"
259 #include "StDetectorDbMaker/St_tpcPadrowT0C.h"
260 #include "StDetectorDbMaker/St_tpcSectorT0offsetC.h"
261 #include "StDetectorDbMaker/St_tpcRDOT0offsetC.h"
262 #include "StDetectorDbMaker/St_tss_tssparC.h"
263 #include "StDetectorDbMaker/St_tpcPadGainT0BC.h"
264 #include "StDetectorDbMaker/St_tpcPadConfigC.h"
265 #include "StDetectorDbMaker/St_tpcPadPlanesC.h"
266 #include "StDetectorDbMaker/St_iTPCSurveyC.h"
267 #include "StDetectorDbMaker/St_starTriggerDelayC.h"
269 #include "StThreeVectorD.hh"
270 #if defined (__SUNPRO_CC) && __SUNPRO_CC >= 0x500
271 using namespace units;
273 static Int_t _debug = 0;
274 StTpcCoordinateTransform::StTpcCoordinateTransform(
StTpcDb* )
276 if (St_tpcPadConfigC::instance()
277 && StTpcDb::instance()->Electronics()
279 && StTpcDb::instance()->GlobalPosition()
282 mTimeBinWidth = 1./StTpcDb::instance()->Electronics()->samplingFrequency();
283 mInnerSectorzOffset = StTpcDb::instance()->Dimensions()->zInnerOffset();
284 mOuterSectorzOffset = StTpcDb::instance()->Dimensions()->zOuterOffset();
286 mInnerSectorzOffset_West = StTpcDb::instance()->Dimensions()->zInnerOffset_West();
287 mOuterSectorzOffset_West = StTpcDb::instance()->Dimensions()->zOuterOffset_West();
291 gMessMgr->Error() <<
"StTpcDb IS INCOMPLETE! Cannot contstruct Coordinate transformation." << endm;
292 assert(St_tpcPadConfigC::instance());
293 assert(StTpcDb::instance()->Electronics());
295 assert(StTpcDb::instance()->GlobalPosition());
303 Int_t sector = a.fromSector();
304 Int_t row = a.fromRow();
305 if (row < 1 || row > St_tpcPadConfigC::instance()->numberOfRows(sector)) row = rowFromLocal(a);
307 Double_t probablePad = padFromLocal(a);
309 Double_t zoffset = 0;
310 if (a.position().z() < 3) zoffset = (row>St_tpcPadConfigC::instance()->innerPadRows(sector)) ? mOuterSectorzOffset :mInnerSectorzOffset;
312 Double_t zoffset = (row>St_tpcPadConfigC::instance()->innerPadRows(sector)) ? mOuterSectorzOffset :mInnerSectorzOffset;
315 if (sector <= 12) zoffset+= (row>St_tpcPadConfigC::instance()->innerPadRows(sector)) ? mOuterSectorzOffset_West :mInnerSectorzOffset_West;
317 Double_t t0offset = (useT0 && sector>=1&§or<=24) ? St_tpcPadGainT0BC::instance()->T0(sector,row,TMath::Nint (probablePad)) : 0;
318 t0offset *= mTimeBinWidth;
319 if (! useT0 && useTau)
320 t0offset -= 3.0 * St_tss_tssparC::instance()->tau();
321 Double_t t0zoffset = t0offset*StTpcDb::instance()->DriftVelocity(sector,row)*1e-6;
322 Double_t tb = tBFromZ(a.position().z()+zoffset-t0zoffset,sector,row,probablePad);
329 Int_t sector = a.sector();
332 if (a.timeBucket() > 6) zoffset = (a.row()>St_tpcPadConfigC::instance()->innerPadRows(sector)) ? mOuterSectorzOffset : mInnerSectorzOffset;
334 Double_t zoffset = (a.row()>St_tpcPadConfigC::instance()->innerPadRows(sector)) ? mOuterSectorzOffset : mInnerSectorzOffset;
337 if (a.sector() <= 12) zoffset+= (a.row() > St_tpcPadConfigC::instance()->innerPadRows(sector)) ? mOuterSectorzOffset_West :mInnerSectorzOffset_West;
339 Double_t t0offset = useT0 ? St_tpcPadGainT0BC::instance()->T0(a.sector(),a.row(),TMath::Nint(a.pad())) : 0;
340 t0offset *= mTimeBinWidth;
341 if (! useT0 && useTau)
342 t0offset -= 3.0 * St_tss_tssparC::instance()->tau();
343 Double_t t0zoffset = t0offset*StTpcDb::instance()->DriftVelocity(a.sector(),a.row())*1e-6;
345 Double_t z = zFromTB(a.timeBucket(),a.sector(),a.row(),a.pad())-zoffset+t0zoffset;
350 Double_t StTpcCoordinateTransform::padFromX(Double_t x, Int_t sector, Int_t row)
const {
351 if (row > St_tpcPadConfigC::instance()->numberOfRows(sector)) row = St_tpcPadConfigC::instance()->numberOfRows(sector);
352 Double_t pitch = (row <= St_tpcPadConfigC::instance()->innerPadRows(sector)) ?
353 St_tpcPadConfigC::instance()->innerSectorPadPitch(sector) :
354 St_tpcPadConfigC::instance()->outerSectorPadPitch(sector);
356 Int_t npads = St_tpcPadConfigC::instance()->numberOfPadsAtRow(sector,row);
358 Int_t NiRows = St_tpcPadConfigC::instance()->numberOfInnerRows(sector);
359 if (NiRows != 13 && row <= NiRows) {
361 Double_t yRef = St_tpcPadConfigC::instance()->radialDistanceAtRow(sector,NiRows) + 0.565;
363 Double_t yHit = St_tpcPadConfigC::instance()->radialDistanceAtRow(sector,row) - yRef;
365 Double_t dx = sur->dx(sector-1);
367 Double_t Xscale = sur->ScaleX(sector-1);
369 Double_t theta = sur->Angle(sector-1);
370 xL = xHit*(1. - Xscale) - dx + theta*yHit;
373 Double_t probablePad = (npads+1.)/2. - xL/pitch;
375 if(probablePad<0.500001) {
376 probablePad=0.500001;
379 cout <<
"StTpcCoordinateTransform::padFromX(" << x <<
"," << sector <<
"," << row <<
"); npads = " << npads <<
", pitch = " << pitch
380 <<
"\tprobablePad " << probablePad << endl;
382 return (probablePad);
385 Double_t StTpcCoordinateTransform::xFromPad(Int_t sector, Int_t row, Double_t pad)
const {
386 if (row > St_tpcPadConfigC::instance()->numberOfRows(sector)) row = St_tpcPadConfigC::instance()->numberOfRows(sector);
387 Double_t pitch = (row <= St_tpcPadConfigC::instance()->innerPadRows(sector)) ?
388 St_tpcPadConfigC::instance()->innerSectorPadPitch(sector) :
389 St_tpcPadConfigC::instance()->outerSectorPadPitch(sector);
390 Int_t npads = St_tpcPadConfigC::instance()->numberOfPadsAtRow(sector,row);
391 Double_t xPad = -pitch*(pad - (npads+1.)/2.);
393 cout <<
"StTpcCoordinateTransform::xFromPad(" << sector <<
"," << row <<
"," << pad <<
"); npads = " << npads <<
", pitch = " << pitch
394 <<
"\txPad = " << xPad << endl;
396 Int_t NiRows = St_tpcPadConfigC::instance()->numberOfInnerRows(sector);
397 if (NiRows == 13 || row > NiRows) {
403 Double_t yRef = St_tpcPadConfigC::instance()->radialDistanceAtRow(sector,NiRows) + 0.565;
405 Double_t yL = St_tpcPadConfigC::instance()->radialDistanceAtRow(sector,row) - yRef;
407 Double_t dx = sur->dx(sector-1);
409 Double_t Xscale = sur->ScaleX(sector-1);
411 Double_t theta = sur->Angle(sector-1);
412 Double_t xHit = xL*(1. + Xscale) + dx - theta*yL;
420 Double_t StTpcCoordinateTransform::zFromTB(Double_t tb, Int_t sector, Int_t row, Int_t pad)
const {
421 if (row > St_tpcPadConfigC::instance()->numberOfRows(sector)) row = St_tpcPadConfigC::instance()->numberOfRows(sector);
424 if (! St_starTriggerDelayC::instance()->Table()->IsMarked()) {
425 trigT0 = St_starTriggerDelayC::instance()->clocks()*mTimeBinWidth;
426 elecT0 = St_starTriggerDelayC::instance()->tZero();
428 trigT0 = StTpcDb::instance()->triggerTimeOffset()*1e6;
430 if ((sector <= 12 && tb <= 350) ||
431 (sector > 12 && tb > 350)) {trigT0 += StTpcDb::instance()->triggerTimeOffsetWest()*1e6;}
433 elecT0 = StTpcDb::instance()->Electronics()->tZero();
435 Double_t sectT0 = St_tpcPadrowT0C::instance()->T0(sector,row);
436 Double_t t0 = trigT0 + elecT0 + sectT0;
438 if ( St_tpcPadConfigC::instance()->IsRowInner(sector,row)) l += 24;
439 Double_t tbx = tb + St_tpcSectorT0offsetC::instance()->t0offset(l);
440 if (St_tpcRDOT0offsetC::instance()->IsShfited(sector)) {
441 tbx += St_tpcRDOT0offsetC::instance()->T0(sector,row,pad);
443 Double_t time = t0 + tbx*mTimeBinWidth;
444 Double_t z = StTpcDb::instance()->DriftVelocity(sector,row)*1e-6*time;
448 Double_t StTpcCoordinateTransform::tBFromZ(Double_t z, Int_t sector, Int_t row, Int_t pad)
const {
449 if (row > St_tpcPadConfigC::instance()->numberOfRows(sector)) row = St_tpcPadConfigC::instance()->numberOfRows(sector);
452 if (! St_starTriggerDelayC::instance()->Table()->IsMarked()) {
453 trigT0 = St_starTriggerDelayC::instance()->clocks()*mTimeBinWidth;
454 elecT0 = St_starTriggerDelayC::instance()->tZero();
456 trigT0 = StTpcDb::instance()->triggerTimeOffset()*1e6;
458 if ((sector <= 12 && z < 195) ||
459 (sector > 12 && z > 195)) {trigT0 += StTpcDb::instance()->triggerTimeOffsetWest()*1e6;}
461 elecT0 = StTpcDb::instance()->Electronics()->tZero();
463 Double_t sectT0 = St_tpcPadrowT0C::instance()->T0(sector,row);
464 Double_t t0 = trigT0 + elecT0 + sectT0;
465 Double_t time = z / (StTpcDb::instance()->DriftVelocity(sector,row)*1e-6);
467 if ( St_tpcPadConfigC::instance()->IsRowInner(sector,row)) l += 24;
468 Double_t tb = (time - t0)/mTimeBinWidth - St_tpcSectorT0offsetC::instance()->t0offset(l);
469 if (St_tpcRDOT0offsetC::instance()->IsShfited(sector)) tb -= St_tpcRDOT0offsetC::instance()->T0(sector,row,pad);
474 Int_t StTpcCoordinateTransform::rowFromLocalY(Double_t y, Int_t sector) {
475 static Int_t Nrows = 0;
476 static Double_t *Radii = 0;
478 if (Nrows != St_tpcPadConfigC::instance()->padRows(sector)) {
479 Nrows = St_tpcPadConfigC::instance()->padRows(sector);
480 if (Radii)
delete [] Radii;
481 Radii =
new Double_t[Nrows+1];
482 for (Int_t i = 1; i <= Nrows+1; i++) {
484 Radii[i-1] = (3*St_tpcPadConfigC::instance()->radialDistanceAtRow(sector,i)
485 - St_tpcPadConfigC::instance()->radialDistanceAtRow(sector,i+1))/2;
486 }
else if (i == Nrows + 1) {
487 Radii[i-1] = (3*St_tpcPadConfigC::instance()->radialDistanceAtRow(sector,i-1)
488 - St_tpcPadConfigC::instance()->radialDistanceAtRow(sector,i-2))/2;
490 Radii[i-1] = (St_tpcPadConfigC::instance()->radialDistanceAtRow(sector,i-1) +
491 St_tpcPadConfigC::instance()->radialDistanceAtRow(sector,i))/2;
495 Long64_t row = TMath::BinarySearch(Nrows+1, Radii, y) + 1;
496 if (row <= 0) row = 1;
497 if (row > Nrows) row = Nrows;
501 Nrows = St_tpcPadPlanesC::instance()->padRows();
502 Radii =
new Double_t[Nrows];
503 for (Int_t i = 1; i <= Nrows; i++) {
504 Radii[i-1] = St_tpcPadPlanesC::instance()->radialDistanceAtRow(i);
507 if (y < Radii[0])
return 1;
508 if (y > Radii[Nrows-1])
return Nrows;
509 Long64_t row = TMath::BinarySearch(Nrows, Radii, y);
510 if (row < Nrows - 1) {
511 if (TMath::Abs(Radii[row]-y) > TMath::Abs(Radii[row+1]-y)) row++;
521 Int_t row = a.fromRow();
522 Int_t sector = a.fromSector();
523 if (row < 1 || row > St_tpcPadConfigC::instance()->numberOfRows(sector)) row = rowFromLocal(a);
524 StTpcDb::instance()->Pad2Tpc(a.sector(),row).LocalToMasterVect(a.position().xyz(),xGG.xyz());
525 const Double_t *trans = StTpcDb::instance()->Pad2Tpc(sector,row).GetTranslation();
526 TGeoTranslation GG2TPC(trans[0],trans[1],trans[2]);
527 GG2TPC.LocalToMaster(xGG.xyz(), b.position().xyz());
528 b.setSector(a.sector()); b.setRow(row);
533 Int_t row = a.fromRow();
534 Int_t sector = a.fromSector();
535 if ( ! (row >= 1 && row <= St_tpcPadConfigC::instance()->numberOfRows(sector))) {
537 StTpcDb::instance()->SupS2Tpc(sector).MasterToLocalVect(a.position().xyz(),xyzS.xyz());
538 row = rowFromLocalY(xyzS[0], sector);
540 const Double_t *trans = StTpcDb::instance()->Pad2Tpc(a.sector(),row).GetTranslation();
541 TGeoTranslation GG2TPC(trans[0],trans[1],trans[2]);
543 GG2TPC.MasterToLocal(a.position().xyz(), xGG.xyz());
544 StTpcDb::instance()->Pad2Tpc(a.sector(),row).MasterToLocalVect(xGG.xyz(),b.position().xyz()); b.setSector(a.sector()); b.setRow(row);