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