105 #include "StFtpcFastSimu.hh"
106 #include "StFtpcParamReader.hh"
107 #include "StFtpcDbReader.hh"
108 #include "StFtpcGeantReader.hh"
111 #include "StMessMgr.h"
112 #include "PhysicalConstants.h"
114 #include "RanluxEngine.h"
116 #include "RandGauss.h"
123 TObjArray *pointarray,
124 TObjArray *geantarray)
129 memset(&mStart,0,&mEnd-&mStart+1);
138 nPoints=mGeant->numberOfHits();
142 nPadrows = mDb->numberOfPadrows();
143 nrowmax =
new Int_t[nPadrows];
144 memset(nrowmax,0,nPadrows*
sizeof(Int_t));
145 nrow =
new Int_t[nPadrows*nPoints];
146 memset(nrow,0,(nPadrows*nPoints)*
sizeof(Int_t));
167 pointarray->Expand(nPoints);
168 geantarray->Expand(nPoints);
170 for (Int_t i = 0; i < nPoints; i++) {
196 delete[] mGeantPoint;
202 StFtpcFastSimu::~StFtpcFastSimu()
207 int StFtpcFastSimu::ffs_gen_padres()
210 float check1, check2;
211 float xi, yi, zi, phi_local, Rh, Vh, Timeb;
212 float sigTimeb, sigPhi, sigma_tr;
213 float sigma_l, sigma_z;
216 float twist_cosine,twist, theta, cross_ang;
220 float xo, yo, zo, sigma_x, sigma_y;
237 check1 = abs((
int)s_rad[0])+abs((
int)s_rad[1])+abs((
int)s_rad[2])+abs((
int)s_rad[3]);
238 check2 = abs((
int)s_azi[0])+abs((
int)s_azi[1])+abs((
int)s_azi[2])+abs((
int)s_azi[3]);
240 if(check1==0. && check2 == 0. )
247 for(k = 0; k<nPoints; k++)
251 xi = mPoint[k].GetX();
252 yi = mPoint[k].GetY();
253 zi = mPoint[k].GetZ();
258 if (mGeant->geantPlane(mGeant->geantVolume(k)) <=10 )
259 phi_local = atan2((
double) yi,(
double) -xi);
261 phi_local = atan2((
double) yi,(
double) xi);
266 Rh = ::sqrt(xi*xi + yi*yi);
269 Vh = Vhm[0] + Vhm[1]*Rh + Vhm[2]*Rh*Rh + Vhm[3]*Rh*Rh*Rh;
272 Timeb = Tbm[0] + Tbm[1]*Rh + Tbm[2]*Rh*Rh + Tbm[3]*Rh*Rh*Rh;
280 if((mGeantPoint[k].GetLocalMomentum(0)==0.)||
281 (mGeantPoint[k].GetLocalMomentum(0)==0.)||
282 (mGeantPoint[k].GetLocalMomentum(0)==0.))
290 r = sqrt ( sqr(mGeant->x(k)) +
292 pt = sqrt ( sqr(mGeant->pLocalX(k)) +
293 sqr(mGeant->pLocalY(k)));
294 twist_cosine=(mGeant->pLocalX(k)*mGeant->x(k)+
295 mGeant->pLocalY(k)*mGeant->y(k))/(r*pt);
297 if ( twist_cosine > 1.0 )
299 if ( twist_cosine < -1.0 )
301 twist = (radian/degree)*acos(twist_cosine);
304 theta = (radian/degree)*
305 atan2((
double) (pt*cos(twist*degree)),
306 (
double) ((mGeant->z(k)
307 /fabs(mGeant->z(k)))*
308 mGeant->pLocalZ(k)));
311 cross_ang = (radian/degree)*
312 atan2((
double) (pt*cos(fabs(90.-twist)*degree)),
313 (
double) ((mGeant->z(k)/fabs(mGeant->z(k)))*
314 mGeant->pLocalZ(k)));
315 alpha = fabs(cross_ang*degree);
319 lambda = fabs(theta*degree);
328 sigPhi = err_azi[0]+err_azi[1]*Rh+err_azi[2]*sqr(Rh)+err_azi[3]*sqr(Rh)*Rh;
331 sigma_tr = ::sqrt(sqr(sigPhi)+(sqr(mDb->padLength()*tan(alpha))));
338 sigTimeb = err_rad[0] + err_rad[1]*Rh + err_rad[2]*sqr(Rh) +
339 err_rad[3]*sqr(Rh)*Rh;
342 sigma_l = ::sqrt(sqr(sigTimeb)+sqr(mDb->padLength()*tan(lambda)));
357 ffs_hit_smear( phi_local, xi, yi, zi, &xo, &yo, &zo,
358 sigma_l, sigma_tr,&sigma_z,&sigma_x,&sigma_y,
364 mPoint[k].SetXerr(sigma_x);
365 mPoint[k].SetYerr(sigma_y);
366 mPoint[k].SetZerr(sigma_z);
371 int StFtpcFastSimu::ffs_hit_rd()
379 ih_max = mGeant->numberOfHits();
383 for(ih= 0; ih<ih_max; ih++)
387 mGeantPoint[ih].SetGeantPID(mGeant->trackPid(ih));
388 mGeantPoint[ih].SetTrackPointer(mGeant->track(ih)+1);
389 mGeantPoint[ih].SetPrimaryTag(mGeant->trackType(ih));
390 if(mGeant->trackCharge(ih) < 0.0)
392 mGeantPoint[ih].SetPrimaryTag(-1*mGeantPoint[ih].GetPrimaryTag());
396 mPoint[ih].SetPadRow(mGeant->geantPlane(mGeant->geantVolume(ih)));
399 mGeantPoint[ih].SetVertexMomentum(mGeant->pVertexX(ih),mGeant->pVertexY(ih),mGeant->pVertexZ(ih));
402 mGeantPoint[ih].SetVertexPosition(mGeant->vertexX(ih),mGeant->vertexY(ih),mGeant->vertexZ(ih));
405 mGeantPoint[ih].SetGeantProcess(mGeant->productionProcess(ih));
408 mGeantPoint[ih].SetLocalMomentum(mGeant->pLocalX(ih),mGeant->pLocalY(ih),mGeant->pLocalZ(ih));
410 mPoint[ih].SetX(mGeant->x(ih));
411 mPoint[ih].SetY(mGeant->y(ih));
412 mPoint[ih].SetZ(mGeant->z(ih));
415 mPoint[ih].SetSector(mGeant->geantSector(mGeant->geantVolume(ih)));
418 mPoint[ih].SetMaxADC(
int( mParam->adcConversionFactor() * mGeant->energyLoss(ih) ));
419 mPoint[ih].SetCharge((
int)(mParam->clusterChargeConversionFactor()*mPoint[ih].GetMaxADC()));
421 mPoint[ih].SetNumberPads(mParam->numberOfPadsDedxSmearing());
422 mPoint[ih].SetNumberBins(mParam->numberOfBinsDedxSmearing());
432 int StFtpcFastSimu::ffs_hit_smear(
float phi,
458 *st_dev_x = sqr(cos(phi)) * sqr(st_dev_l) + sqr(sin(phi)) * sqr(st_dev_t);
459 *st_dev_x = (::sqrt(*st_dev_x))*micrometer;
461 *st_dev_y = sqr(sin(phi)) * sqr(st_dev_l) + sqr(cos(phi)) * sqr(st_dev_t);
462 *st_dev_y = sqrt (*st_dev_y)*micrometer;
464 smear=(float) quasiRandom->shoot();
465 err_pad = st_dev_t*smear;
467 smear=(float) quasiRandom->shoot();
468 err_drft = st_dev_l*smear;
474 err_x = cos(phi) * err_drft - sin(phi) * err_pad;
475 *xo = xi + err_x*micrometer;
477 err_y = sin(phi) * err_drft + cos(phi) * err_pad;
478 *yo = yi + err_y*micrometer;
486 int StFtpcFastSimu::ffs_ini()
490 ri = mDb->sensitiveVolumeInnerRadius()+mParam->radiusTolerance();
491 ra = mDb->sensitiveVolumeOuterRadius()-mParam->radiusTolerance();
494 Vhm[0] = mParam->vDriftEstimates(0);
495 Vhm[1] = mParam->vDriftEstimates(1);
496 Vhm[2] = mParam->vDriftEstimates(2);
497 Vhm[3] = mParam->vDriftEstimates(3);
500 Tbm[0] = mParam->tDriftEstimates(0);
501 Tbm[1] = mParam->tDriftEstimates(1);
502 Tbm[2] = mParam->tDriftEstimates(2);
503 Tbm[3] = mParam->tDriftEstimates(3);
506 s_rad[0] = mParam->sigmaRadialEstimates(0);
507 s_rad[1] = mParam->sigmaRadialEstimates(1);
512 s_azi[0] = mParam->sigmaAzimuthalEstimates(0);
513 s_azi[1] = mParam->sigmaAzimuthalEstimates(1);
518 err_rad[0] = mParam->errorRadialEstimates(0);
519 err_rad[1] = mParam->errorRadialEstimates(1);
524 err_azi[0] = mParam->errorAzimuthalEstimates(0);
525 err_azi[1] = mParam->errorAzimuthalEstimates(1);
529 LOG_INFO <<
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << endm;
530 LOG_INFO <<
"Parametrization for vd, Td, sig_rad and sig_azi, err_rad and err_azi:" << endm;
531 LOG_INFO <<
"vd=" << Vhm[0]<<
"+"<<Vhm[1]<<
"x+"<<Vhm[2]<<
"xx+"
532 <<Vhm[3]<<
"xxx" << endm;
533 LOG_INFO <<
"Td="<<Tbm[0]<<
"+"<<Tbm[1]<<
"x+"<<Tbm[2]<<
"xx+"<<Tbm[3]
535 LOG_INFO <<
"sig_rad="<<s_rad[0]<<
"+"<<s_rad[1]<<
"x+"<<s_rad[2]
536 <<
"xx+"<<s_rad[3]<<
"xxx" << endm;
537 LOG_INFO <<
"sig_azi="<<s_azi[0]<<
"+"<<s_azi[1]<<
"x+"<<s_azi[2]
538 <<
"xx+"<<s_azi[3]<<
"xxx" << endm;
539 LOG_INFO <<
"err_rad="<<err_rad[0]<<
"+"<<err_rad[1]<<
"x+"<<err_rad[2]
540 <<
"xx+"<<err_rad[3]<<
"xxx" << endm;
541 LOG_INFO <<
"err_azi="<<err_azi[0]<<
"+"<<err_azi[1]<<
"x+"<<err_azi[2]
542 <<
"xx+"<<err_azi[3]<<
"xxx" << endm;
543 LOG_INFO <<
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" << endm;
546 Va = Vhm[0] + Vhm[1]*ra + Vhm[2]*sqr(ra) + Vhm[3]*ra*sqr(ra);
549 phimin = degree * mDb->phiOrigin();
552 phisec = degree * mDb->phiPerSector();
556 sector_phi_min = mDb->radiansPerBoundary()/2 + 2*mDb->radiansPerPad();
560 sector_phi_max = phisec-sector_phi_min;
565 Int_t StFtpcFastSimu::ffs_merge_tagger()
568 Int_t id_1, id_2, rem_count1, rem_count2, n_gepoints;
569 Float_t sig_azi_1, v1, sig_rad_1;
570 Float_t dist_rad_in, dist_rad_out;
571 Float_t delta_azi, delta_r;
576 Float_t * sigazi =
new float[nPoints];
577 Float_t * sigrad =
new float[nPoints];
578 Float_t * r1 =
new float[nPoints];
579 Float_t * phi1_local =
new float[nPoints];
584 for(i=0; i<nPoints; i++)
586 mPoint[i].SetFlags(0);
589 r1[i] = ::sqrt(sqr(mPoint[i].GetX()) + sqr(mPoint[i].GetY()));
590 if (mPoint[i].GetPadRow() <= 10 )
591 phi1_local[i] = atan2((
double) mPoint[i].GetY(),
592 (
double) -mPoint[i].GetX());
594 phi1_local[i] = atan2((
double) mPoint[i].GetY(),
595 (
double) mPoint[i].GetX());
596 if ( phi1_local[i] < 0.0 )
597 phi1_local[i] += twopi;
599 sig_azi_1 = s_azi[0] + s_azi[1]*r1[i] +
600 s_azi[2]*sqr(r1[i]) + s_azi[3]*sqr(r1[i])*r1[i];
601 mPoint[i].SetSigmaPhi(sig_azi_1*micrometer*(r1[i]/ra));
603 sig_azi_1 = (mParam->sigmaSpacingFactor()*sig_azi_1)*micrometer;
604 sigazi[i] = sig_azi_1*(r1[i]/ra);
607 v1 = Vhm[0]+Vhm[1]*r1[i] + Vhm[2]*sqr(r1[i])+
608 Vhm[3]*sqr(r1[i])*r1[i];
609 sig_rad_1 = s_rad[0] + s_rad[1]*r1[i] +
610 s_rad[2]*sqr(r1[i]) + s_rad[3]*sqr(r1[i])*r1[i];
612 mPoint[i].SetSigmaR(sig_rad_1*micrometer*(v1/Va));
614 sig_rad_1 = (mParam->sigmaSpacingFactor()*sig_rad_1)*micrometer;
615 sigrad[i] = sig_rad_1*(v1/Va);
619 for(h=0;h<nPadrows;h++)
624 for(i=0;i<nrowmax[h];i++)
626 id_1 = nrow[h*nPoints+i]-1;
628 for(j=i+1; j<nrowmax[h]; j++)
630 id_2 = nrow[h*nPoints+j]-1;
631 if((mPoint[id_2].GetFlags()==mParam->mergedClusterFlag()) ||
632 (mPoint[id_2].GetSector()!=mPoint[id_1].GetSector()))
635 delta_azi = fabs(phi1_local[id_1]-phi1_local[id_2])
636 *((r1[id_1]+r1[id_2])/2);
637 delta_r = fabs(r1[id_1]-r1[id_2]);
639 if((delta_r < (2 * sigrad[id_1])) &&
640 (delta_azi < (2 * sigazi[id_1])))
643 if(mPoint[id_1].GetFlags() != mParam->mergedClusterFlag())
645 mPoint[id_1].SetFlags(mParam->unfoldedClusterFlag());
647 mPoint[id_2].SetFlags(mParam->unfoldedClusterFlag());
650 if((delta_r<sigrad[id_1]) &&
651 (delta_azi<sigazi[id_1]))
656 if(mPoint[id_1].GetFlags() != mParam->mergedClusterFlag())
658 mPoint[id_1].SetFlags(mParam->badShapeClusterFlag());
660 mPoint[id_2].SetFlags(mParam->mergedClusterFlag());
661 mPoint[id_1].SetMaxADC(mPoint[id_1].GetMaxADC()+
662 mPoint[id_2].GetMaxADC() / 2);
664 mPoint[id_1].SetCharge(mPoint[id_1].GetCharge() +
665 mPoint[id_2].GetCharge());
667 mPoint[id_1].SetX((mPoint[id_1].GetX() +
668 mPoint[id_2].GetX()) / 2);
669 mPoint[id_1].SetY((mPoint[id_1].GetY() +
670 mPoint[id_2].GetY()) / 2);
671 mPoint[id_1].SetZ((mPoint[id_1].GetZ() +
672 mPoint[id_2].GetZ()) / 2);
674 mPoint[id_1].SetSigmaPhi(mPoint[id_1].GetSigmaPhi()+
675 mPoint[id_2].GetSigmaPhi() / 2);
676 mPoint[id_1].SetSigmaR(mPoint[id_1].GetSigmaR()+
677 mPoint[id_2].GetSigmaR() / 2);
693 dist_rad_in = s_rad[0] + s_rad[1]*ri + s_rad[2]*sqr(ri) +
695 dist_rad_out = s_rad[0] + s_rad[1]*ra + s_rad[2]*sqr(ra) +
698 dist_rad_in *= 2.*micrometer;
699 dist_rad_out *= 2.*micrometer;
701 while(id_2 < nPoints)
703 delta_azi = phi1_local[id_2]
704 -myModulo(((mPoint[id_2].GetSector()-1)*phisec+phimin),(twopi));
708 if((delta_azi < sector_phi_min) ||
709 (delta_azi > sector_phi_max) ||
710 (r1[id_2] < ri+dist_rad_in) ||
711 (r1[id_2] > ra-dist_rad_out) ||
712 (mPoint[id_2].GetFlags() == mParam->mergedClusterFlag()))
714 if(mPoint[id_2].GetFlags() == mParam->mergedClusterFlag())
732 mPoint[id_1].SetPadRow(mPoint[id_2].GetPadRow());
733 mPoint[id_1].SetSector(mPoint[id_2].GetSector());
734 mPoint[id_1].SetNumberPads(mPoint[id_2].GetNumberPads());
735 mPoint[id_1].SetNumberBins(mPoint[id_2].GetNumberBins());
736 mPoint[id_1].SetMaxADC(mPoint[id_2].GetMaxADC());
737 mPoint[id_1].SetCharge(mPoint[id_2].GetCharge());
738 mPoint[id_1].SetFlags(mPoint[id_2].GetFlags());
739 mGeantPoint[id_1].SetTrackPointer(mGeantPoint[id_2].GetTrackPointer());
740 mGeantPoint[id_1].SetGeantPID(mGeantPoint[id_2].GetGeantPID());
741 mGeantPoint[id_1].SetPrimaryTag(mGeantPoint[id_2].GetPrimaryTag());
742 mPoint[id_1].SetX(mPoint[id_2].GetX());
743 mPoint[id_1].SetY(mPoint[id_2].GetY());
744 mPoint[id_1].SetZ(mPoint[id_2].GetZ());
745 mPoint[id_1].SetSigmaPhi(mPoint[id_2].GetSigmaPhi());
746 mPoint[id_1].SetSigmaR(mPoint[id_2].GetSigmaR());
747 mGeantPoint[id_1].SetVertexMomentum(mGeantPoint[id_2].GetVertexMomentum(0),
748 mGeantPoint[id_2].GetVertexMomentum(1),
749 mGeantPoint[id_2].GetVertexMomentum(2));
750 mGeantPoint[id_1].SetLocalMomentum(mGeantPoint[id_2].GetLocalMomentum(0),
751 mGeantPoint[id_2].GetLocalMomentum(1),
752 mGeantPoint[id_2].GetLocalMomentum(2));
753 mGeantPoint[id_1].SetVertexPosition(mGeantPoint[id_2].GetVertexPosition(0),
754 mGeantPoint[id_2].GetVertexPosition(1),
755 mGeantPoint[id_2].GetVertexPosition(2));
756 mGeantPoint[id_1].SetGeantProcess(mGeantPoint[id_2].GetGeantProcess());
764 nPoints = n_gepoints;
766 LOG_INFO <<
"Deleted " << rem_count1 <<
" merged clusters" << endm;
767 LOG_INFO <<
"Deleted " << rem_count2 <<
" clusters on sector limit" << endm;
768 LOG_INFO <<
" " << nPoints<<
" clusters found" << endm;
773 delete [] phi1_local;
778 int StFtpcFastSimu::ffs_tag()
787 for(k=0; k<nPadrows; k++)
793 for(i = 0; i< nPoints; i++)
795 k = mPoint[i].GetPadRow();
797 nrow[(k-1)*nPoints+(nrowmax[k-1]-1)] = i+1;