00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017 #include <iostream>
00018 #include <iomanip>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include "l3CoordinateTransformer.h"
00022
00023 #include <unistd.h>
00024 #include <sys/mman.h>
00025 #include <errno.h>
00026
00027 #include <sys/types.h>
00028 #include <sys/stat.h>
00029 #include <fcntl.h>
00030 #include <rtsLog.h>
00031
00032 using namespace std;
00033
00034
00035 l3CoordinateTransformer::l3CoordinateTransformer()
00036 {
00037
00038
00039
00040
00041 transformation_errors =0;
00042
00043
00044 Set_parameters_by_hand() ;
00045
00046
00047
00048
00049
00050 TPCmap = NULL;
00051
00052 }
00053
00054
00055 l3CoordinateTransformer::~l3CoordinateTransformer()
00056 {
00057
00058
00059
00060
00061
00062
00063 if(TPCmap) free(TPCmap);
00064 TPCmap = NULL;
00065 }
00066
00067 #include "mapbin.h"
00068
00069 int l3CoordinateTransformer::LoadTPCLookupTable(char *)
00070 {
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 if(TPCmap) return 0;
00094
00095 void *file = (void *)mapdotbinfile;
00096
00097
00098 int type = ((int *)file)[0];
00099 if ((type != 3) && (type != 100)) {
00100
00101 LOG(ERR, "No valid map found header file",0,0,0,0,0);
00102 return -1;
00103 }
00104
00105 int headerSize = ((int *)file)[1];
00106
00107 dpad = ((float *)file)[3];
00108 dtb = ((float *)file)[4];
00109 maxtb = ((float *)file)[5];
00110
00111 npad = (int) ceil( 182. / dpad);
00112 ntb = (int) ceil( maxtb / dtb);
00113
00114 TPCmap = (float *)malloc( MAPDOTBINFILE_SZ - headerSize*4);
00115 if (TPCmap == NULL) {
00116 LOG(ERR, "Cannot allocate memory for lookup table.\n");
00117 return -1;
00118 } else if (TPCmap == (float*)-1) {
00119 LOG(ERR, "TPCmap=-1. What's that??? 0x%x", TPCmap);
00120 }
00121
00122 memcpy(TPCmap, ((float *)file)+headerSize, MAPDOTBINFILE_SZ - headerSize*4);
00123
00124 return 0;
00125 }
00126
00127
00128 void l3CoordinateTransformer::raw_to_global(const l3ptrsCoordinate &raw ,
00129 l3xyzCoordinate &global)
00130 {
00131
00132 typedef float binmap_t[45][npad+1][ntb+1][3];
00133 binmap_t *binmap = (binmap_t *)TPCmap;
00134
00135
00136
00137 int ipad = (int)floor(raw.Getp()/dpad);
00138 int itb = (int)floor(raw.Gett()/dtb);
00139
00140
00141 float wpad = raw.Getp()/dpad - (float)ipad;
00142 float wtb = raw.Gett()/dtb - (float)itb;
00143
00144 int sec = (int)raw.Gets() - 1;
00145 int row = (int)raw.Getr() - 1;
00146
00147 float x1 = binmap[sec][row][ipad ][itb ][0];
00148 float y1 = binmap[sec][row][ipad ][itb ][1];
00149 float z1 = binmap[sec][row][ipad ][itb ][2];
00150 float x2 = binmap[sec][row][ipad+1][itb ][0];
00151 float y2 = binmap[sec][row][ipad+1][itb ][1];
00152 float z2 = binmap[sec][row][ipad+1][itb ][2];
00153 float x3 = binmap[sec][row][ipad+1][itb+1][0];
00154 float y3 = binmap[sec][row][ipad+1][itb+1][1];
00155 float z3 = binmap[sec][row][ipad+1][itb+1][2];
00156 float x4 = binmap[sec][row][ipad ][itb+1][0];
00157 float y4 = binmap[sec][row][ipad ][itb+1][1];
00158 float z4 = binmap[sec][row][ipad ][itb+1][2];
00159
00160
00161
00162 float x = (1-wpad)*(1-wtb)*x1 + wpad*(1-wtb)*x2
00163 + wpad*wtb*x3 + (1-wpad)*wtb*x4;
00164 float y = (1-wpad)*(1-wtb)*y1 + wpad*(1-wtb)*y2
00165 + wpad*wtb*y3 + (1-wpad)*wtb*y4;
00166 float z = (1-wpad)*(1-wtb)*z1 + wpad*(1-wtb)*z2
00167 + wpad*wtb*z3 + (1-wpad)*wtb*z4;
00168
00169 global.Setxyz(x,y,z);
00170
00171 }
00172
00173 void l3CoordinateTransformer::raw_to_local(const l3ptrsCoordinate &raw ,
00174 l3xyzCoordinate &local )
00175 {
00176 double pitch = (raw.Getr()<14) ? innerSectorPadPitch : outerSectorPadPitch;
00177 double pads2move = raw.Getp() - numberOfPadsAtRow[(int)raw.Getr()-1]/2;
00178 local.Setx( pitch * (pads2move - 0.5) ) ;
00179 local.Sety( radialDistanceAtRow[(int)(raw.Getr())-1] ) ;
00180
00181
00182 if( raw.Getr() <= 13 )
00183 {
00184 local.Setz(drift_length_inner - raw.Gett() * lengthPerTb) ;
00185 if (raw.Gett()>max_tb_inner) {
00186 transformation_errors++;
00187 }
00188 }
00189 else
00190 {
00191 local.Setz(drift_length_outer - raw.Gett() * lengthPerTb) ;
00192 if (raw.Gett()>max_tb_outer) {
00193 transformation_errors++;
00194 }
00195 }
00196 }
00197
00198 void l3CoordinateTransformer::local_to_global(const l3ptrsCoordinate &raw ,
00199 const l3xyzCoordinate &local,
00200 l3xyzCoordinate &global )
00201 {
00202 int sector = (int) raw.Gets();
00203
00204
00205
00206
00207
00208
00209
00210 double x = SectorCos[sector-1] * local.Getx() + SectorSin[sector-1] * local.Gety();
00211 if (sector>12) x = -x;
00212 double y = -1.* SectorSin[sector-1] * local.Getx() +
00213 SectorCos[sector-1] * local.Gety();
00214 double z = (sector<13) ? local.Getz() : -local.Getz() ;
00215
00216 global.Setxyz(x,y,z);
00217
00218 }
00219
00220 void l3CoordinateTransformer::global_to_raw(const l3xyzCoordinate &global,
00221 l3ptrsCoordinate &raw )
00222 {
00223 l3xyzCoordinate local(0,0,0) ;
00224 global_to_local( global, local, raw ) ;
00225
00226
00227 local_to_raw( global ,local ,raw ) ;
00228 }
00229
00230 void l3CoordinateTransformer::global_to_raw(int sector, int row,
00231 const l3xyzCoordinate &global,
00232 l3ptrsCoordinate &raw )
00233 {
00234 l3xyzCoordinate local(0,0,0) ;
00235 global_to_local( sector, row, global, local ) ;
00236 local_to_raw( row ,local ,raw ) ;
00237 }
00238
00239 void l3CoordinateTransformer::global_to_local(const l3xyzCoordinate &global,
00240 l3xyzCoordinate &local,
00241 l3ptrsCoordinate &raw)
00242 {
00243
00244
00245
00246 double y = global.Gety() ;
00247 if (y== 0) y= 0.000000001;
00248
00249 double x = 0;
00250 if(global.Getz()>=0)
00251 {
00252 x = global.Getx() ;
00253 local.Setz(global.Getz());
00254 }
00255 else
00256 {
00257 x = -(global.Getx()) ;
00258 local.Setz(-(global.Getz()));
00259 }
00260
00261
00262 double pi = 3.14159265358979323846;
00263 double sec_border = tan(pi/12) ;
00264 double turn_angle = -pi/6 ;
00265 double sin_turn_angle = sin(turn_angle);
00266 double cos_turn_angle = cos(turn_angle);
00267 double sector = 0 ;
00268
00269 if (y>=0 && fabs(x/y)<=sec_border)
00270 {
00271
00272 sector = 12 ;
00273 }
00274 else
00275 {
00276
00277 while( y<0 || (fabs(x/y)>sec_border))
00278 {
00279 double xn = x*cos_turn_angle + y*sin_turn_angle ;
00280 double yn = -x*sin_turn_angle + y*cos_turn_angle ;
00281 x = xn ;
00282 y = yn ;
00283 sector++;
00284 }
00285 }
00286
00287
00288 local.Setx(x);
00289 local.Sety(y);
00290
00291 if (global.Getz()<0)
00292 {
00293 raw.Sets(sector+12);
00294 }
00295 else
00296 {
00297 raw.Sets(sector);
00298 }
00299
00300 }
00301
00302 void l3CoordinateTransformer::global_to_local( int sector, int row,
00303 const l3xyzCoordinate &global,
00304 l3xyzCoordinate &local )
00305 {
00306
00307
00308
00309
00310
00311
00312
00313 double xGlobal = global.Getx();
00314 if (sector>12) xGlobal = -xGlobal;
00315
00316 double x = SectorCos[sector-1] * xGlobal - SectorSin[sector-1] * global.Gety() ;
00317 double y = SectorSin[sector-1] * xGlobal + SectorCos[sector-1] * global.Gety() ;
00318 double z = fabs(global.Getz());
00319
00320 local.Setxyz(x,y,z);
00321
00322 return ;
00323 }
00324
00325 void l3CoordinateTransformer::local_to_raw(const l3xyzCoordinate &global,
00326 const l3xyzCoordinate &local,
00327 l3ptrsCoordinate &raw )
00328 {
00329
00330 double y = local.Gety() ;
00331 int row = 0;
00332 int row_index = 0 ;
00333 while( (fabs(radialDistanceAtRow[row_index]-y) > 0.5) && (row_index < 46) )
00334 {
00335 row_index++;
00336 }
00337 if (row_index==45 || y<59)
00338 {
00339
00340
00341 return ;
00342 }
00343 else
00344 {
00345
00346 row = row_index+1;
00347 }
00348
00349
00350 double x = local.Getx();
00351 double pitch = (row<=13) ? innerSectorPadPitch : outerSectorPadPitch ;
00352 int half_num_pads_this_row = numberOfPadsAtRow[row-1]/2 ;
00353 double pad = half_num_pads_this_row + x/pitch + 0.5 ;
00354
00355
00356 double bucket = 0;
00357 double z = local.Getz();
00358 if (row<=13)
00359 {
00360 bucket = ( drift_length_inner - z )/lengthPerTb ;
00361 if (z>drift_length_inner) {
00362 transformation_errors++;
00363 }
00364 }
00365 else
00366 {
00367 bucket = ( drift_length_outer - z )/lengthPerTb ;
00368 if (z>drift_length_outer) {
00369 transformation_errors++;
00370 }
00371 }
00372
00373
00374 raw.Setp(pad);
00375 raw.Sett(bucket);
00376 raw.Setr(row);
00377 }
00378
00379 void l3CoordinateTransformer::local_to_raw( int row ,
00380 const l3xyzCoordinate &local ,
00381 l3ptrsCoordinate &raw )
00382 {
00383
00384 double x = local.Getx();
00385 double pitch = (row<=13) ? innerSectorPadPitch : outerSectorPadPitch ;
00386 int half_num_pads_this_row = numberOfPadsAtRow[row-1]/2 ;
00387 double pad = half_num_pads_this_row + x/pitch + 0.5 ;
00388
00389
00390 double bucket = 0;
00391 double z = local.Getz();
00392 if (row<=13)
00393 {
00394 bucket = ( drift_length_inner - z )/lengthPerTb ;
00395 if (z>drift_length_inner) {
00396 transformation_errors++;
00397 }
00398 }
00399 else
00400 {
00401 bucket = ( drift_length_outer - z )/lengthPerTb ;
00402 if (z>drift_length_outer) {
00403 transformation_errors++;
00404 }
00405 }
00406
00407
00408 raw.Setp(pad);
00409 raw.Sett(bucket);
00410 raw.Setr(row);
00411 }
00412
00413 void l3CoordinateTransformer::Set_parameters_by_hand( const double mlengthPerTb,
00414 const double mdrift_length_inner,
00415 const double mdrift_length_outer)
00416 {
00417 lengthPerTb = mlengthPerTb ;
00418 drift_length_inner = mdrift_length_inner ;
00419 drift_length_outer = mdrift_length_outer ;
00420
00421
00422 max_tb_inner = drift_length_inner/lengthPerTb;
00423 max_tb_outer = drift_length_outer/lengthPerTb;
00424 }
00425
00426
00427
00428 void l3CoordinateTransformer::Use_transformation_provided_by_db()
00429 {
00430 #ifdef L3OFFLINE
00431
00432
00433
00434 StTpcPadCoordinate padco;
00435 StGlobalCoordinate glo;
00436 StTpcCoordinateTransform tra(gStTpcDb);
00437
00438
00439 double tau3 = 3 * (gStTpcDb->Electronics()->tau() * 1e-09)
00440 * (gStTpcDb->DriftVelocity()) ;
00441
00442
00443 padco.setSector(1);
00444 padco.setRow(5);
00445 padco.setPad(1);
00446 padco.setTimeBucket(100);
00447
00448 tra(padco,glo);
00449 double z_100 = glo.position().z();
00450 padco.setTimeBucket(0);
00451 tra(padco,glo);
00452 double z_0 = glo.position().z();
00453 double lengthPerTb_inner = fabs((z_0-z_100)/100) ;
00454 drift_length_inner = fabs(glo.position().z()+tau3);
00455
00456
00457
00458
00459
00460
00461 padco.setSector(1);
00462 padco.setRow(30);
00463 padco.setPad(1);
00464 padco.setTimeBucket(100);
00465 tra(padco,glo);
00466 z_100 = glo.position().z();
00467 padco.setTimeBucket(0);
00468 tra(padco,glo);
00469 z_0 = glo.position().z();
00470 double lengthPerTb_outer = fabs((z_0-z_100)/100) ;
00471 drift_length_outer = fabs(glo.position().z()+tau3) ;
00472
00473
00474
00475
00476
00477
00478 if (lengthPerTb_outer == lengthPerTb_inner )
00479 {
00480 lengthPerTb = lengthPerTb_outer ;
00481 }
00482 else
00483 {
00484 cerr << "Different driftvelocities in TPC observed -> Set to 0. " << endl;
00485 lengthPerTb = 0;
00486 }
00487
00488
00489
00490 max_tb_inner = drift_length_inner/lengthPerTb;
00491 max_tb_outer = drift_length_outer/lengthPerTb;
00492
00493 #else
00494 cout << "This is not functional online.\n" ;
00495 #endif
00496
00497 };
00498
00499
00500
00501 void l3CoordinateTransformer::Get_parameters_from_db()
00502 {
00503 #ifdef L3OFFLINE
00504
00505 double driftvelocity = gStTpcDb->DriftVelocity();
00506 double inner_effective_driftlength =
00507 gStTpcDb->Dimensions()->innerEffectiveDriftDistance();
00508 double outer_effective_driftlength =
00509 gStTpcDb->Dimensions()->outerEffectiveDriftDistance();
00510 double gatingrid = gStTpcDb->Dimensions()->gatingGridZ();
00511 double t0pad = gStTpcDb->T0(1)->getT0(1,1);
00512 double zinneroffset = gStTpcDb->Dimensions()->zInnerOffset();
00513 double zouteroffset = gStTpcDb->Dimensions()->zOuterOffset();
00514 double frequency = gStTpcDb->Electronics()->samplingFrequency();
00515 double tzero = gStTpcDb->Electronics()->tZero();
00516 double tau = gStTpcDb->Electronics()->tau();
00517 double shapingtime = gStTpcDb->Electronics()->shapingTime();
00518
00519 if (0)
00520 {
00521 cout << "Fresh from the db we got : \n" ;
00522 cout << "The driftvelocity : " << driftvelocity << endl;
00523 cout << "The effective innerdrift (not used) : "
00524 << inner_effective_driftlength << endl ;
00525 cout << "The effective outerdrift (not used) : "
00526 << outer_effective_driftlength << endl ;
00527 cout << "Innerzoffset : " << zinneroffset << endl ;
00528 cout << "Outerzoffset : " << zouteroffset << endl ;
00529 cout << "Gatinggrid : " << gatingrid << endl ;
00530 cout << "t0pad : " << t0pad << endl ;
00531 cout << "The tzero : " << tzero << endl;
00532 cout << "Frequency ist set to : " << frequency << endl;
00533 cout << "tau : " << tau << endl ;
00534 cout << "shapingtime (not used) : " << shapingtime << endl ;
00535 }
00536
00537
00538 lengthPerTb = 1 / frequency / (1E6) * driftvelocity ;
00539
00540
00541
00542
00543
00544 drift_length_inner = gatingrid-driftvelocity*1e-6*(-tzero+0.5/frequency)+
00545 zinneroffset+t0pad+3*tau*1e-09*driftvelocity;
00546 drift_length_outer = gatingrid-driftvelocity*1e-6*(-tzero+0.5/frequency)+
00547 zouteroffset+t0pad+3*tau*1e-09*driftvelocity;
00548
00549
00550 if (0)
00551 {
00552 cout << "inner drift length : " << drift_length_inner << endl;
00553 cout << "outer drift length : " << drift_length_outer << endl;
00554 cout << "lengthPerTb : " << lengthPerTb << endl;
00555 }
00556
00557
00558 max_tb_inner = drift_length_inner/lengthPerTb;
00559 max_tb_outer = drift_length_outer/lengthPerTb;
00560
00561 #else
00562 cout << "This is not functional online.\n" ;
00563 #endif
00564
00565 };
00566
00567
00568
00569 void l3CoordinateTransformer::Print_parameters()
00570 {
00571 cout << "l3CoordinateTransformer: Parameters used <== " << endl ;
00572 cout << " Used parameters : " << endl ;
00573 cout << " Length per tb : " << lengthPerTb << endl ;
00574 cout << " drift_length_inner: " << drift_length_inner << endl ;
00575 cout << " drift_length_outer: " << drift_length_outer << endl ;
00576 cout << " max_tb_inner : " << max_tb_inner << endl ;
00577 cout << " max_tb_outer : " << max_tb_outer << endl ;
00578
00579 };
00580
00582
00584 double l3CoordinateTransformer::outerSectorPadPitch = 0.67;
00585 double l3CoordinateTransformer::innerSectorPadPitch = 0.335;
00586
00587
00588 int l3CoordinateTransformer::numberOfPadsAtRow[] = {
00589 88,96,104,112,118,126,134,142,150,158,166,174,182,
00590 98,100,102,104,106,106,108,110,112,112,114,116,
00591 118,120,122,122,124,126,128,128,130,132,134,136,
00592 138,138,140,142,144,144,144,144
00593 };
00594
00595 double l3CoordinateTransformer::radialDistanceAtRow[] = {
00596 60.0, 64.8, 69.6, 74.4, 79.2, 84.0, 88.8, 93.60,
00597 98.8, 104., 109.20, 114.4, 119.6,
00598 127.195, 129.195, 131.195, 133.195, 135.195,
00599 137.195, 139.195, 141.195, 143.195, 145.195,
00600 147.195, 149.195, 151.195, 153.195, 155.195,
00601 157.195, 159.195, 161.195, 163.195, 165.195,
00602 167.195, 169.195, 171.195, 173.195, 175.195,
00603 177.195, 179.195, 181.195, 183.195, 185.195,
00604 187.195, 189.195
00605 };
00606
00607 double l3CoordinateTransformer::SectorSin[] = {
00608 0.5, 0.866025404,
00609 1.0, 0.866025404,
00610 0.5, 0.,
00611 -0.5, -0.866025404,
00612 -1.0, -0.866025404,
00613 -0.5, 0.,
00614 0.5, 0.866025404,
00615 1.0, 0.866025404,
00616 0.5, 0.,
00617 -0.5, -0.866025404,
00618 -1.0, -0.866025404,
00619 -0.5, 0.
00620 };
00621
00622 double l3CoordinateTransformer::SectorCos[] = {
00623 0.866025404, 0.5,
00624 0., -0.5,
00625 -0.866025404, -1.0,
00626 -0.866025404, -0.5,
00627 0., 0.5,
00628 0.866025404, 1.0,
00629 0.866025404, 0.5,
00630 0., -0.5,
00631 -0.866025404, -1.0,
00632 -0.866025404, -0.5,
00633 0., 0.5,
00634 0.866025404, 1.0
00635 };
00636