16 #include "Stl3Util/base/St_l3_Coordinate_Transformer.h"
18 #include "Stl3Util/ftf/FtfGeneral.h"
19 #include "Stl3Util/base/FtfLog.h"
20 #include "StMultiArray.h"
26 #include "Stl3Util/base/FtfLog.h"
34 #include <sys/types.h>
40 St_l3_Coordinate_Transformer::St_l3_Coordinate_Transformer()
47 transformation_errors =0;
50 Set_parameters_by_hand() ;
61 St_l3_Coordinate_Transformer::~St_l3_Coordinate_Transformer()
69 if(TPCmap) free(TPCmap);
75 int St_l3_Coordinate_Transformer::LoadTPCLookupTable(
const char * mapfilename)
79 ftfLog(
"Transformation tables not available under Solaris\n");
85 if (TPCmap) free(TPCmap);
89 int fd = open(mapfilename, O_RDONLY);
93 ftfLog(
"Unable to open transformation map '%s'.Aborting.\n",
99 int filesize = lseek(fd, 0, SEEK_END);
100 void *file = mmap(0, filesize, PROT_READ, MAP_PRIVATE, fd, 0);
101 if ( file == MAP_FAILED ) {
102 ftfLog(
"Unable to mmap transformation map '%s'.Aborting.\n",
108 int type = ((
int *)file)[0];
109 if ((type != 3) && (type != 100)) {
111 ftfLog(
"No valid map found in %s.\n", mapfilename);
115 int headerSize = ((
int *)file)[1];
117 dpad = ((
float *)file)[3];
118 dtb = ((
float *)file)[4];
119 maxtb = ((
float *)file)[5];
121 npad = (int) ceil( 182. / dpad);
122 ntb = (int) ceil( maxtb / dtb);
125 TPCmap = (
float *)malloc(filesize - headerSize*4);
126 if (TPCmap == NULL) {
127 ftfLog(
"Cannot allocate memory for lookup table.\n", mapfilename);
131 memcpy(TPCmap, (
float *)file+headerSize, filesize - headerSize*4);
134 if (munmap((
char*)file, filesize))
135 ftfLog(
"St_l3_Coordinate_Transformer: error munmapping %s\n",
138 ftfLog(
"St_l3_Coordinate_Transformer: error closing %s\n",
142 ftfLog(
"St_l3_Coordinate_Transformer: loaded conversion map \"%s\"\n",
157 raw_to_local(raw, local);
158 local_to_global(raw, local, global);
168 raw_to_local(raw, local);
169 local_to_global(raw, local, global);
178 int ipad = (int)floor(raw.Getp()/dpad);
179 int itb = (int)floor(raw.Gett()/dtb);
182 float wpad = raw.Getp()/dpad - (float)ipad;
183 float wtb = raw.Gett()/dtb - (float)itb;
185 int sec = (int)raw.Gets() - 1;
186 int row = (int)raw.Getr() - 1;
188 float x1 = binmap[sec][row][ipad ][itb ][0];
189 float y1 = binmap[sec][row][ipad ][itb ][1];
190 float z1 = binmap[sec][row][ipad ][itb ][2];
191 float x2 = binmap[sec][row][ipad+1][itb ][0];
192 float y2 = binmap[sec][row][ipad+1][itb ][1];
193 float z2 = binmap[sec][row][ipad+1][itb ][2];
194 float x3 = binmap[sec][row][ipad+1][itb+1][0];
195 float y3 = binmap[sec][row][ipad+1][itb+1][1];
196 float z3 = binmap[sec][row][ipad+1][itb+1][2];
197 float x4 = binmap[sec][row][ipad ][itb+1][0];
198 float y4 = binmap[sec][row][ipad ][itb+1][1];
199 float z4 = binmap[sec][row][ipad ][itb+1][2];
203 float x = (1-wpad)*(1-wtb)*x1 + wpad*(1-wtb)*x2
204 + wpad*wtb*x3 + (1-wpad)*wtb*x4;
205 float y = (1-wpad)*(1-wtb)*y1 + wpad*(1-wtb)*y2
206 + wpad*wtb*y3 + (1-wpad)*wtb*y4;
207 float z = (1-wpad)*(1-wtb)*z1 + wpad*(1-wtb)*z2
208 + wpad*wtb*z3 + (1-wpad)*wtb*z4;
210 global.Setxyz(x,y,z);
218 double pitch = (raw.Getr()<14) ? innerSectorPadPitch : outerSectorPadPitch;
219 double pads2move = raw.Getp() - numberOfPadsAtRow[(int)raw.Getr()-1]/2;
220 local.Setx( pitch * (pads2move - 0.5) ) ;
221 local.Sety( radialDistanceAtRow[(
int)(raw.Getr())-1] ) ;
224 if( raw.Getr() <= 13 )
226 local.Setz(drift_length_inner - raw.Gett() * lengthPerTb) ;
227 if (raw.Gett()>max_tb_inner) {
228 transformation_errors++;
233 local.Setz(drift_length_outer - raw.Gett() * lengthPerTb) ;
234 if (raw.Gett()>max_tb_outer) {
235 transformation_errors++;
242 int sector = (int) raw.Gets();
250 double x = SectorCos[sector-1] * local.Getx() + SectorSin[sector-1] * local.Gety();
251 if (sector>12) x = -x;
252 double y = -1.* SectorSin[sector-1] * local.Getx() + SectorCos[sector-1] * local.Gety();
253 double z = (sector<13) ? local.Getz() : -local.Getz() ;
255 global.Setxyz(x,y,z);
262 global_to_local( global, local, raw ) ;
265 local_to_raw( global ,local ,raw ) ;
268 void St_l3_Coordinate_Transformer::global_to_raw(
int sector,
int row,
273 global_to_local( sector, row, global, local ) ;
274 local_to_raw( row ,local ,raw ) ;
282 double y = global.Gety() ;
283 if (y== 0) y= 0.000000001;
289 local.Setz(global.Getz());
293 x = -(global.Getx()) ;
294 local.Setz(-(global.Getz()));
298 double pi = 3.14159265358979323846;
299 double sec_border = tan(pi/12) ;
300 double turn_angle = -pi/6 ;
301 double sin_turn_angle = sin(turn_angle);
302 double cos_turn_angle = cos(turn_angle);
305 if (y>=0 && fabs(x/y)<=sec_border)
313 while( y<0 || (fabs(x/y)>sec_border))
315 double xn = x*cos_turn_angle + y*sin_turn_angle ;
316 double yn = -x*sin_turn_angle + y*cos_turn_angle ;
338 void St_l3_Coordinate_Transformer::global_to_local(
349 double xGlobal = global.Getx();
350 if (sector>12) xGlobal = -xGlobal;
352 double x = SectorCos[sector-1] * xGlobal - SectorSin[sector-1] * global.Gety() ;
353 double y = SectorSin[sector-1] * xGlobal + SectorCos[sector-1] * global.Gety() ;
354 double z = fabs(global.Getz());
364 double y = local.Gety() ;
367 while( (fabs(radialDistanceAtRow[row_index]-y) > 0.5) && (row_index < 46) )
371 if (row_index==45 || y<59)
384 double x = local.Getx();
385 double pitch = (row<=13) ? innerSectorPadPitch : outerSectorPadPitch ;
386 int half_num_pads_this_row = numberOfPadsAtRow[row-1]/2 ;
387 double pad = half_num_pads_this_row + x/pitch + 0.5 ;
391 double z = local.Getz();
394 bucket = ( drift_length_inner - z )/lengthPerTb ;
395 if (z>drift_length_inner) {
396 transformation_errors++;
401 bucket = ( drift_length_outer - z )/lengthPerTb ;
402 if (z>drift_length_outer) {
403 transformation_errors++;
416 double x = local.Getx();
417 double pitch = (row<=13) ? innerSectorPadPitch : outerSectorPadPitch ;
418 int half_num_pads_this_row = numberOfPadsAtRow[row-1]/2 ;
419 double pad = half_num_pads_this_row + x/pitch + 0.5 ;
423 double z = local.Getz();
426 bucket = ( drift_length_inner - z )/lengthPerTb ;
427 if (z>drift_length_inner) {
428 transformation_errors++;
433 bucket = ( drift_length_outer - z )/lengthPerTb ;
434 if (z>drift_length_outer) {
435 transformation_errors++;
445 void St_l3_Coordinate_Transformer::Set_parameters_by_hand(
const double mlengthPerTb,
446 const double mdrift_length_inner,
447 const double mdrift_length_outer)
449 lengthPerTb = mlengthPerTb ;
450 drift_length_inner = mdrift_length_inner ;
451 drift_length_outer = mdrift_length_outer ;
454 max_tb_inner = drift_length_inner/lengthPerTb;
455 max_tb_outer = drift_length_outer/lengthPerTb;
460 void St_l3_Coordinate_Transformer::Use_transformation_provided_by_db()
471 double tau3 = 3 * (gStTpcDb->Electronics()->tau() * 1e-09) * (gStTpcDb->DriftVelocity()) ;
477 padco.setTimeBucket(100);
480 double z_100 = glo.position().z();
481 padco.setTimeBucket(0);
483 double z_0 = glo.position().z();
484 double lengthPerTb_inner = fabs((z_0-z_100)/100) ;
485 drift_length_inner = fabs(glo.position().z()+tau3);
495 padco.setTimeBucket(100);
497 z_100 = glo.position().z();
498 padco.setTimeBucket(0);
500 z_0 = glo.position().z();
501 double lengthPerTb_outer = fabs((z_0-z_100)/100) ;
502 drift_length_outer = fabs(glo.position().z()+tau3) ;
509 if (lengthPerTb_outer == lengthPerTb_inner )
511 lengthPerTb = lengthPerTb_outer ;
515 cerr <<
"Different driftvelocities in TPC observed -> Set to 0. " << endl;
521 max_tb_inner = drift_length_inner/lengthPerTb;
522 max_tb_outer = drift_length_outer/lengthPerTb;
525 cout <<
"This is not functional online.\n" ;
532 void St_l3_Coordinate_Transformer::Get_parameters_from_db()
536 double driftvelocity = gStTpcDb->DriftVelocity();
537 double inner_effective_driftlength = gStTpcDb->Dimensions()->innerEffectiveDriftDistance();
538 double outer_effective_driftlength = gStTpcDb->Dimensions()->outerEffectiveDriftDistance();
539 double gatingrid = gStTpcDb->Dimensions()->gatingGridZ();
540 double t0pad = gStTpcDb->T0(1)->getT0(1,1);
541 double zinneroffset = gStTpcDb->Dimensions()->zInnerOffset();
542 double zouteroffset = gStTpcDb->Dimensions()->zOuterOffset();
543 double frequency = gStTpcDb->Electronics()->samplingFrequency();
544 double tzero = gStTpcDb->Electronics()->tZero();
545 double tau = gStTpcDb->Electronics()->tau();
546 double shapingtime = gStTpcDb->Electronics()->shapingTime();
550 cout <<
"Fresh from the db we got : \n" ;
551 cout <<
"The driftvelocity : " << driftvelocity << endl;
552 cout <<
"The effective innerdrift (not used) : " << inner_effective_driftlength << endl ;
553 cout <<
"The effective outerdrift (not used) : " << outer_effective_driftlength << endl ;
554 cout <<
"Innerzoffset : " << zinneroffset << endl ;
555 cout <<
"Outerzoffset : " << zouteroffset << endl ;
556 cout <<
"Gatinggrid : " << gatingrid << endl ;
557 cout <<
"t0pad : " << t0pad << endl ;
558 cout <<
"The tzero : " << tzero << endl;
559 cout <<
"Frequency ist set to : " << frequency << endl;
560 cout <<
"tau : " << tau << endl ;
561 cout <<
"shapingtime (not used) : " << shapingtime << endl ;
565 lengthPerTb = 1 / frequency / (1E6) * driftvelocity ;
571 drift_length_inner = gatingrid-driftvelocity*1e-6*(-tzero+0.5/frequency)+zinneroffset+t0pad+3*tau*1e-09*driftvelocity;
572 drift_length_outer = gatingrid-driftvelocity*1e-6*(-tzero+0.5/frequency)+zouteroffset+t0pad+3*tau*1e-09*driftvelocity;
577 cout <<
"inner drift length : " << drift_length_inner << endl;
578 cout <<
"outer drift length : " << drift_length_outer << endl;
579 cout <<
"lengthPerTb : " << lengthPerTb << endl;
583 max_tb_inner = drift_length_inner/lengthPerTb;
584 max_tb_outer = drift_length_outer/lengthPerTb;
587 cout <<
"This is not functional online.\n" ;
594 void St_l3_Coordinate_Transformer::Print_parameters()
596 cout <<
"St_l3_Coordinate_Transformer: Parameters used <== " << endl ;
597 cout <<
" Used parameters : " << endl ;
598 cout <<
" Length per tb : " << lengthPerTb << endl ;
599 cout <<
" drift_length_inner: " << drift_length_inner << endl ;
600 cout <<
" drift_length_outer: " << drift_length_outer << endl ;
601 cout <<
" max_tb_inner : " << max_tb_inner << endl ;
602 cout <<
" max_tb_outer : " << max_tb_outer << endl ;
609 double St_l3_Coordinate_Transformer::outerSectorPadPitch = 0.67;
610 double St_l3_Coordinate_Transformer::innerSectorPadPitch = 0.335;
613 int St_l3_Coordinate_Transformer::numberOfPadsAtRow[] = {
614 88,96,104,112,118,126,134,142,150,158,166,174,182,
615 98,100,102,104,106,106,108,110,112,112,114,116,
616 118,120,122,122,124,126,128,128,130,132,134,136,
617 138,138,140,142,144,144,144,144
620 double St_l3_Coordinate_Transformer::radialDistanceAtRow[] = {
621 60.0, 64.8, 69.6, 74.4, 79.2, 84.0, 88.8, 93.60,
622 98.8, 104., 109.20, 114.4, 119.6,
623 127.195, 129.195, 131.195, 133.195, 135.195,
624 137.195, 139.195, 141.195, 143.195, 145.195,
625 147.195, 149.195, 151.195, 153.195, 155.195,
626 157.195, 159.195, 161.195, 163.195, 165.195,
627 167.195, 169.195, 171.195, 173.195, 175.195,
628 177.195, 179.195, 181.195, 183.195, 185.195,
632 double St_l3_Coordinate_Transformer::SectorSin[] = {
647 double St_l3_Coordinate_Transformer::SectorCos[] = {