267 #include "StMessMgr.h"
268 #include "StFtpcClusterFinder.hh"
269 #include "StFtpcTrackMaker/StFtpcConfMapPoint.hh"
270 #include "math_constants.h"
274 #include "PhysicalConstants.h"
276 #include "asic_map_correction.h"
281 StFtpcClusterFinder::StFtpcClusterFinder(
StFTPCReader *reader,
284 TObjArray *pointarray,
291 LOG_DEBUG <<
"StFtpcClusterFinder constructed for production" << endm;
293 mParam = paramReader;
302 MAXSEQPEAKS = mParam->maxNumSeqPeaks();
303 MAXPEAKS = mParam->maxNumPeaks();
304 MAXLOOPS = mParam->maxLoops();
305 MAXFASTLOOPS = mParam->maxFastLoops();
306 UNFOLDLIMIT = mParam->unfoldLimit();
307 UNFOLDFAILEDLIMIT = mParam->unfoldFailedLimit();
309 mMinTimeBin = mDb->minTimeBin();
310 mMinTimeBinMed = mDb->minTimeBinMed();
311 mMinTimeBinOut = mDb->minTimeBinOut();
313 mMaxPadlength = mDb->maxPadLength();
314 mMaxTimelength = mDb->maxTimeLength();
315 mMaxPadlengthMed = mDb->maxPadLengthMed();
316 mMaxTimelengthMed = mDb->maxTimeLengthMed();
317 mMaxPadlengthOut = mDb->maxPadLengthOut();
318 mMaxTimelengthOut = mDb->maxTimeLengthOut();
320 DeltaTime = mDb->deltaTime();
321 DeltaPad = mDb->deltaPad();
323 mMinChargeWindow = mDb->minChargeWindow();
325 mOffsetCathodeWest = mDb->offsetCathodeWest();
326 mOffsetCathodeEast = mDb->offsetCathodeEast();
327 mAngleOffsetWest = mDb->angleOffsetWest();
328 mAngleOffsetEast = mDb->angleOffsetEast();
337 StFtpcClusterFinder::StFtpcClusterFinder(
StFTPCReader *reader,
340 TObjArray *pointarray,
348 LOG_DEBUG <<
"StFtpcClusterFinder constructed for calibration" << endm;
350 mParam = paramReader;
359 MAXSEQPEAKS = mParam->maxNumSeqPeaks();
360 MAXPEAKS = mParam->maxNumPeaks();
361 MAXLOOPS = mParam->maxLoops();
362 MAXFASTLOOPS = mParam->maxFastLoops();
363 UNFOLDLIMIT = mParam->unfoldLimit();
364 UNFOLDFAILEDLIMIT = mParam->unfoldFailedLimit();
366 mMinTimeBin = mDb->minTimeBin();
367 mMinTimeBinMed = mDb->minTimeBinMed();
368 mMinTimeBinOut = mDb->minTimeBinOut();
370 mMaxPadlength = mDb->maxPadLength();
371 mMaxTimelength = mDb->maxTimeLength();
372 mMaxPadlengthMed = mDb->maxPadLengthMed();
373 mMaxTimelengthMed = mDb->maxTimeLengthMed();
374 mMaxPadlengthOut = mDb->maxPadLengthOut();
375 mMaxTimelengthOut = mDb->maxTimeLengthOut();
377 DeltaTime = mDb->deltaTime();
378 DeltaPad = mDb->deltaPad();
380 mMinChargeWindow = mDb->minChargeWindow();
385 mOffsetCathodeWest = 0.0;
386 mOffsetCathodeEast = 0.0;
387 mAngleOffsetWest = 0.0;
388 mAngleOffsetEast = 0.0;
395 mMinChargeWindow = 30;
396 mMaxPadlengthOut = 30;
397 mMaxTimelengthOut = 30;
405 StFtpcClusterFinder::~StFtpcClusterFinder()
410 int StFtpcClusterFinder::search()
413 Double_t *pradius = 0;
414 Double_t *pdeflection = 0;
415 int iRow, iSec, iPad, iPadBuf;
416 int iRowBuf, iSecBuf;
417 int firstPadrowToSearch;
420 int iNowSeqIndex, iNewSeqIndex, iOldSeqNumber, iOldSeqIndex;
421 int iCUCSequence, iMoveSequence, iOldSeqBuf;
422 int bOldSequenceUsed, bLastSequence;
423 TClusterUC *FirstCUC, *CurrentCUC, *LastCUC, *DeleteCUC;
425 TPCSequence *OldSequences, *NewSequences, *(SequencePointer[3]);
431 double deltaAirPressure;
435 int CUCMemoryArray[MAXNUMCUC];
439 pradius =
new Double_t[mParam->numberOfDriftSteps()
440 *mDb->numberOfPadrowsPerSide()];
441 memset(pradius, 0, (mParam->numberOfDriftSteps()*mDb->numberOfPadrowsPerSide())*
sizeof(Double_t));
442 pdeflection =
new Double_t[mParam->numberOfDriftSteps()
443 *mDb->numberOfPadrowsPerSide()];
444 memset(pdeflection, 0, (mParam->numberOfDriftSteps()*mDb->numberOfPadrowsPerSide())*
sizeof(Double_t));
446 if(pradius == 0 || pdeflection == 0)
448 LOG_ERROR <<
"Padtrans memory allocation failed, exiting!" << endm;
449 if (pradius != 0)
delete[] pradius;
450 if (pdeflection != 0)
delete[] pdeflection;
456 firstPadrowToSearch = 0;
457 deltaAirPressure = 0;
461 for (
int iftpc=0; iftpc<2; iftpc++) {
463 deltaAirPressure = mParam->adjustedAirPressureWest() - mParam->standardPressure();
464 firstPadrowToSearch = mDb->firstPadrowToSearch() - 1;
465 LOG_DEBUG <<
"Ftpc West: deltaAirPressure = adjustedAirPressureWest ("<<mParam->adjustedAirPressureWest()<<
") - standardPressure ("<<mParam->standardPressure()<<
") = "<<deltaAirPressure<<endm;
468 deltaAirPressure = mParam->adjustedAirPressureEast() - mParam->standardPressure();
469 firstPadrowToSearch = mDb->firstPadrowToSearch() - 1 + mDb->numberOfPadrowsPerSide();
470 LOG_DEBUG <<
"Ftpc East: deltaAirPressure = adjustedAirPressureEast ("<<mParam->adjustedAirPressureEast()<<
") - standardPressure ("<<mParam->standardPressure()<<
") = "<<deltaAirPressure<<endm;
474 if(!calcpadtrans(pradius, pdeflection,deltaAirPressure))
476 LOG_ERROR <<
"Couldn't calculate padtrans table, exiting!" << endm;
478 delete[] pdeflection;
483 if(!cucInit(CUCMemory, CUCMemoryArray, &CUCMemoryPtr))
485 LOG_ERROR <<
"Couldn't initialize CUC memory, exiting!" << endm;
487 delete[] pdeflection;
492 for(iIndex=1; iIndex<256; iIndex++)
494 fastlog[iIndex] = ::log((
double) iIndex);
514 for(iRow=firstPadrowToSearch,iRowBuf=firstPadrowToSearch;iRow<firstPadrowToSearch+mDb->numberOfPadrowsPerSide(); iRow++)
516 for(iSec=mDb->firstSectorToSearch()-1,
517 iSecBuf=mDb->firstSectorToSearch()-1;
518 iSec<mDb->lastSectorToSearch(); iSec++)
525 iHardSec = mDb->numberOfSectors()*(int)(iRow/2) + iSec + 1;
526 iHardRow = iRow%2 + 1;
529 LOG_DEBUG<<
"Cluster Finder: Now on Sector "<<iSec<<
", Row "<<iRow<<
" (iHardSec "<<iHardSec<<
", iHardRow "<<iHardRow<<
")"<<endm;
533 unsigned char *(padlist[2]);
534 int iOccPads=mReader->getPadList(iHardSec, iHardRow,
535 padlist[iHardRow-1]);
542 for (iThPad=0; iThPad<160; iThPad++)
543 newpadlist[iThPad]=0;
545 for(iThPad=0; iThPad<iOccPads; iThPad++)
547 iPad=padlist[iHardRow-1][iThPad];
548 if ( mDb->Asic2EastNotInverted() && iRow>=10 && (iPad>=65 && iPad<=96))
549 newpadlist[padkey[iPad-1]-1] = iPad;
551 newpadlist[iPad-1] = iPad;
555 for(iThPad=0; iThPad<160; iThPad++)
557 if (newpadlist[iThPad] == 0 )
continue;
561 for(CurrentCUC = FirstCUC; CurrentCUC!=0;
562 CurrentCUC = CurrentCUC->NextClusterUC)
565 if(iPad > CurrentCUC->EndPad + 1 || bNewSec)
569 if(CurrentCUC->EndPad > CurrentCUC->StartPad)
575 if (geometryCut(CurrentCUC))
576 if(!findHits(CurrentCUC, iRowBuf, iSecBuf,
577 pradius, pdeflection,
582 LOG_DEBUG<<
"Hitfinder failed! Cluster is lost"<<endm;
586 DeleteCUC=CurrentCUC;
588 if(CurrentCUC==FirstCUC)
590 FirstCUC=CurrentCUC->NextClusterUC;
594 LastCUC->NextClusterUC=CurrentCUC->NextClusterUC;
598 if(!cucFree(CUCMemory, CUCMemoryArray,
599 &CUCMemoryPtr, DeleteCUC))
601 LOG_ERROR <<
"Fatal memory management error." << endm;
603 delete[] pdeflection;
615 OldSequences=NewSequences;
616 iOldSeqNumber=iNewSeqIndex;
629 mReader->getSequences(iHardSec, iHardRow, newpadlist[iThPad], &iNewSeqNumber,
630 SequencePointer[iHardRow]);
631 NewSequences=SequencePointer[iHardRow];
634 for(iNewSeqIndex=0; iNewSeqIndex < iNewSeqNumber;
638 if (mcldebug->drawclhisto!=0)
640 mcldebug->drawhisto(iHardSec,iHardRow,iPad,NewSequences[iNewSeqIndex]);
641 mcldebug->drawgainhisto(iHardSec,iHardRow,iPad,((
float)(mDb->amplitudeSlope((iSec*mDb->numberOfPads()+iPad),iRow))),NewSequences[iNewSeqIndex]);
650 for(entry=0; entry<NewSequences[iNewSeqIndex].Length; entry++)
652 if (mHisto) mHisto->Fill(iHardSec-1,
653 entry+NewSequences[iNewSeqIndex].startTimeBin,
654 NewSequences[iNewSeqIndex].FirstAdc[entry]);
655 if (iHardSec >= 1 && iHardSec <= 30 ) {
656 mHistoW->Fill( entry+NewSequences[iNewSeqIndex].startTimeBin,
657 NewSequences[iNewSeqIndex].FirstAdc[entry]);
659 if (iHardSec >= 31 && iHardSec <= 60 ) {
660 mHistoE->Fill( entry+NewSequences[iNewSeqIndex].startTimeBin,
662 NewSequences[iNewSeqIndex].FirstAdc[entry]);
673 for(iOldSeqIndex=iOldSeqBuf; iOldSeqIndex < iOldSeqNumber;
678 if(((NewSequences[iNewSeqIndex].startTimeBin >=
679 OldSequences[iOldSeqIndex].startTimeBin) &&
680 (NewSequences[iNewSeqIndex].startTimeBin <=
681 OldSequences[iOldSeqIndex].startTimeBin +
682 OldSequences[iOldSeqIndex].Length-1)) ||
683 ((NewSequences[iNewSeqIndex].startTimeBin +
684 NewSequences[iNewSeqIndex].Length-1 >=
685 OldSequences[iOldSeqIndex].startTimeBin) &&
686 (NewSequences[iNewSeqIndex].startTimeBin +
687 NewSequences[iNewSeqIndex].Length-1 <=
688 OldSequences[iOldSeqIndex].startTimeBin +
689 OldSequences[iOldSeqIndex].Length-1)) ||
690 ((OldSequences[iOldSeqIndex].startTimeBin >=
691 NewSequences[iNewSeqIndex].startTimeBin) &&
692 (OldSequences[iOldSeqIndex].startTimeBin <=
693 NewSequences[iNewSeqIndex].startTimeBin +
694 NewSequences[iNewSeqIndex].Length-1)))
698 iOldSeqBuf=iOldSeqIndex;
703 for(CurrentCUC = FirstCUC; CurrentCUC != 0;
704 CurrentCUC = CurrentCUC->NextClusterUC)
709 iCUCSequence<CurrentCUC->NumSequences;
714 if((OldSequences[iOldSeqIndex].startTimeBin ==
715 CurrentCUC->Sequence[iCUCSequence].startTimeBin)
716 && (CurrentCUC->SequencePad[iCUCSequence] ==
722 if(SequenceInCUC!=CurrentCUC)
724 if(SequenceInCUC != 0 && SequenceInCUC!=CurrentCUC)
728 SequenceInCUC->EndPad =
729 SequenceInCUC->StartPad;
731 if(SequenceInCUC->StartPad <
732 CurrentCUC->StartPad)
734 CurrentCUC->StartPad =
735 SequenceInCUC->StartPad;
737 CurrentCUC->EndPad=iPad;
741 (iMoveSequence <SequenceInCUC->NumSequences) &&
742 ( (CurrentCUC->NumSequences+iMoveSequence) < MAXNUMSEQUENCES);
747 CurrentCUC->NumSequences] =
751 SequencePad[iMoveSequence +
752 CurrentCUC->NumSequences] =
754 SequencePad[iMoveSequence];
757 CurrentCUC->NumSequences +=
758 SequenceInCUC->NumSequences;
759 if(CurrentCUC->NumSequences > MAXNUMSEQUENCES)
761 CurrentCUC->NumSequences = MAXNUMSEQUENCES;
765 SequenceInCUC=CurrentCUC;
771 if(CurrentCUC->NumSequences<MAXNUMSEQUENCES)
773 CurrentCUC->Sequence[CurrentCUC->NumSequences]
774 = NewSequences[iNewSeqIndex];
775 CurrentCUC->SequencePad[CurrentCUC->NumSequences]
777 CurrentCUC->NumSequences++;
779 CurrentCUC->EndPad=iPad;
780 SequenceInCUC=CurrentCUC;
783 if(NewSequences[iNewSeqIndex].startTimeBin==0 ||
784 NewSequences[iNewSeqIndex].startTimeBin
785 +NewSequences[iNewSeqIndex].Length
786 ==mDb->numberOfTimebins()-1 ||
787 iPad==mDb->numberOfPads())
789 CurrentCUC->CutOff=1;
796 if(SequenceInCUC==0 && NewSequences[iNewSeqIndex].Length>1)
800 CurrentCUC=cucAlloc(CUCMemory, CUCMemoryArray,
806 LOG_DEBUG<<
"Previous cluster is now lost"<<endm;
810 delete[] pdeflection;
818 FirstCUC = CurrentCUC;
822 LastCUC->NextClusterUC=CurrentCUC;
826 CurrentCUC->NextClusterUC=0;
830 CurrentCUC->StartPad=iPad-1;
831 CurrentCUC->EndPad=iPad;
832 CurrentCUC->NumSequences=2;
835 CurrentCUC->Sequence[0] =
836 OldSequences[iOldSeqIndex];
841 CurrentCUC->SequencePad[0] = iPad-1;
843 CurrentCUC->Sequence[1] =
844 NewSequences[iNewSeqIndex];
845 CurrentCUC->SequencePad[1]=iPad;
846 SequenceInCUC=CurrentCUC;
849 if(iPad==1 || iPad==mDb->numberOfPads() ||
850 CurrentCUC->Sequence[0].startTimeBin==0 ||
851 CurrentCUC->Sequence[0].startTimeBin
852 +CurrentCUC->Sequence[0].Length
853 ==mDb->numberOfTimebins()-1 ||
854 CurrentCUC->Sequence[1].startTimeBin==0 ||
855 CurrentCUC->Sequence[1].startTimeBin
856 +CurrentCUC->Sequence[1].Length
857 ==mDb->numberOfTimebins()-1)
859 CurrentCUC->CutOff=1;
863 CurrentCUC->CutOff=0;
868 if(bOldSequenceUsed==0 && SequenceInCUC!=0)
872 if(SequenceInCUC->NumSequences<MAXNUMSEQUENCES)
874 SequenceInCUC->Sequence[SequenceInCUC->NumSequences]
875 = OldSequences[iOldSeqIndex];
876 SequenceInCUC->SequencePad[SequenceInCUC->NumSequences]
878 SequenceInCUC->NumSequences++;
882 if(OldSequences[iOldSeqIndex].startTimeBin==0 ||
883 OldSequences[iOldSeqIndex].startTimeBin
884 +OldSequences[iOldSeqIndex].Length
885 ==mDb->numberOfTimebins()-1 ||
886 iPad>=mDb->numberOfPads()-1)
888 SequenceInCUC->CutOff=1;
899 for(CurrentCUC = FirstCUC; CurrentCUC!=0;
900 CurrentCUC = CurrentCUC->NextClusterUC)
904 if(CurrentCUC->EndPad > CurrentCUC->StartPad)
910 if (geometryCut(CurrentCUC))
911 if(!findHits(CurrentCUC, iRowBuf, iSecBuf,
912 pradius, pdeflection,
917 LOG_DEBUG<<
"Hitfinder failed! Cluster is lost"<<endm;
921 DeleteCUC=CurrentCUC;
923 if(CurrentCUC==FirstCUC)
925 FirstCUC=CurrentCUC->NextClusterUC;
929 LastCUC->NextClusterUC=CurrentCUC->NextClusterUC;
933 if(!cucFree(CUCMemory, CUCMemoryArray,
934 &CUCMemoryPtr, DeleteCUC))
936 LOG_ERROR <<
"Fatal memory management error." << endm;
938 delete[] pdeflection;
948 westHits = mPoint->GetEntriesFast();
949 LOG_INFO <<
"StFtpcClusterFinder found " << clusters <<
" clusters and processed to " << westHits <<
" hits in Ftpc West." << endm;
952 eastHits = mPoint->GetEntriesFast() - westHits;
953 LOG_INFO <<
"StFtpcClusterFinder found " << clusters <<
" clusters and processed to " << eastHits <<
" hits in Ftpc East." << endm;
958 delete[] pdeflection;
963 bool StFtpcClusterFinder::geometryCut(
TClusterUC *Cluster)
970 for(
int iPad=Cluster->StartPad; iPad<=Cluster->EndPad; iPad++)
972 for(
int iSequence = 0; iSequence < Cluster->NumSequences; iSequence++)
974 if(Cluster->SequencePad[iSequence] == iPad)
976 if (Cluster->Sequence[iSequence].Length > seqlength)
977 seqlength=Cluster->Sequence[iSequence].Length;
978 if (Cluster->Sequence[iSequence].startTimeBin<minTimebin)
979 minTimebin=Cluster->Sequence[iSequence].startTimeBin;
980 if ((Cluster->Sequence[iSequence].startTimeBin+Cluster->Sequence[iSequence].Length) > maxTimebin)
981 maxTimebin=(Cluster->Sequence[iSequence].startTimeBin+Cluster->Sequence[iSequence].Length);
987 if (abs(Cluster->EndPad-Cluster->StartPad)<mMaxPadlengthOut && seqlength<mMaxTimelengthOut)
992 if (minTimebin>mMinTimeBin)
return true;
993 else if ((minTimebin>mMinTimeBinMed && minTimebin<=mMinTimeBin) && abs(Cluster->EndPad-Cluster->StartPad)<mMaxPadlengthMed && seqlength<mMaxTimelengthMed)
995 else if (minTimebin>mMinTimeBinOut && minTimebin<=mMinTimeBinMed && abs(Cluster->EndPad-Cluster->StartPad)<mMaxPadlengthOut && seqlength<mMaxTimelengthOut)
1002 int StFtpcClusterFinder::findHits(
TClusterUC *Cluster,
1006 double *pDeflection,
1016 Peaks =
new TPeak[MAXPEAKS];
1017 float TClSearch [162][258];
1019 for (
int i=0;i<162;i++)
1020 for (
int j=0;j<258;j++)
1030 for(
int iPad=Cluster->StartPad; iPad<=Cluster->EndPad; iPad++)
1032 for(
int iSequence = 0; iSequence < Cluster->NumSequences; iSequence++)
1034 if(Cluster->SequencePad[iSequence] == iPad)
1036 for(
int iIndex=0; iIndex< Cluster->Sequence[iSequence].Length; iIndex++)
1039 cTemp=((float)(
unsigned int)(Cluster->Sequence[iSequence].FirstAdc[iIndex])
1040 * mDb->amplitudeSlope(iSec*mDb->numberOfPads()+iPad,iRow)
1041 + mDb->amplitudeOffset(iSec*mDb->numberOfPads()+iPad,iRow));
1042 Cluster->Sequence[iSequence].FirstAdc[iIndex]=(
unsigned char) cTemp;
1043 TClSearch[iPad][Cluster->Sequence[iSequence].startTimeBin+iIndex]=cTemp;
1055 for(
int iPad=Cluster->StartPad; iPad<=Cluster->EndPad; iPad++)
1057 for(
int iSequence = 0; iSequence < Cluster->NumSequences; iSequence++)
1059 if(Cluster->SequencePad[iSequence] == iPad)
1061 for(
int iTime=Cluster->Sequence[iSequence].startTimeBin; iTime <=Cluster->
Sequence[iSequence].startTimeBin+Cluster->Sequence[iSequence].Length; iTime++)
1073 for (i=iPad-DeltaPad;i<=(iPad+DeltaPad) && (iPad+DeltaPad)<=160 && (iPad-DeltaPad)>=0;i++)
1075 for (k=iTime-DeltaTime;k<=(iTime+DeltaTime) && (iTime+DeltaTime)<=256 && (iTime-DeltaTime)>=0;k++)
1077 if (i<iPad+DeltaPad && i>iPad-DeltaPad && k<iTime+DeltaTime && k>iTime-DeltaTime)
1078 cl_charge=cl_charge+TClSearch[i][k];
1080 if (TClSearch[iPad][iTime]>=TClSearch[i][k]+1.25 && TClSearch[iPad][iTime]>0
1081 && TClSearch[i][k]>0)
1084 else if (TClSearch[iPad][iTime]<TClSearch[i][k] && TClSearch[i][k]>0 && TClSearch[i][k]>0)
1094 if (PeakFound && cl_charge>mMinChargeWindow && iNumPeaks<MAXPEAKS)
1099 if ((Peaks[iNumPeaks-1].Timebin!=iTime && Peaks[iNumPeaks-1].Timebin!=iTime-1 && Peaks[iNumPeaks-1].Timebin!=iTime+1) || Peaks[iNumPeaks-1].pad!=iPad )
1101 Peaks[iNumPeaks].pad=iPad;
1102 Peaks[iNumPeaks].Timebin=iTime;
1103 Peaks[iNumPeaks].Sequence=Cluster->Sequence[iSequence];
1109 Peaks[iNumPeaks].pad=iPad;
1110 Peaks[iNumPeaks].Timebin=iTime;
1111 Peaks[iNumPeaks].Sequence=Cluster->Sequence[iSequence];
1124 if(!fitPoints(Cluster, iRow, iSec, pRadius, pDeflection, Peaks,
1125 iNumPeaks, fastlog))
1128 LOG_DEBUG<<
"Point fitting failed! Cluster is lost."<<endm;
1138 int StFtpcClusterFinder::fitPoints(
TClusterUC* Cluster,
1142 double *pDeflection,
1147 int iRowSAVE, iSecSAVE;
1148 int iADCValue, iADCPlus, iADCMinus;
1149 int iADCTimePlus, iADCTimeMinus;
1150 int iSequence, iBin;
1151 int ChargeSum, PadSum;
1154 int iPeakIndex, iInnerIndex;
1155 int iNumUnfoldLoops;
1156 int BadFit, PeakShifted, FailedFit;
1157 int PadtransPerTimebin, PadtransBin;
1158 float SumDeltaPos, SumDeltaAmp;
1159 float NewTimePosition, NewPadPosition;
1160 float NewPeakHeight, PeakHeightSum;
1161 float fDeltaADC, fDeltaADCPlus, fDeltaADCMinus;
1162 float fDeltaADCTimePlus, fDeltaADCTimeMinus;
1163 float fDriftLength, fRadError, fPhiError;
1165 PadtransPerTimebin=(int) mParam->numberOfDriftSteps()
1166 / mDb->numberOfTimebins();
1171 LOG_DEBUG<<
"Cluster starting "<<Cluster->StartPad<<
", "<<Cluster->Sequence->startTimeBin<<
" has no peak!"<<endm;
1181 for(iSequence = 0; iSequence < Cluster->NumSequences; iSequence++)
1183 for(iBin = 0; iBin < Cluster->Sequence[iSequence].Length; iBin++)
1185 iADCValue = Cluster->Sequence[iSequence].FirstAdc[iBin];
1186 ChargeSum += iADCValue;
1187 PadSum += Cluster->SequencePad[iSequence] * iADCValue;
1188 TimeSum += (Cluster->Sequence[iSequence].startTimeBin + iBin +
1189 mDb->timeOffset(iSec*mDb->numberOfPads()
1190 +Cluster->SequencePad[iSequence],iRow))
1198 Peak->Sequence.FirstAdc[Peak->Timebin - Peak->Sequence.startTimeBin];
1201 iUseGauss=mParam->gaussFittingFlags();
1205 if((iUseGauss & 1) == 1)
1208 iADCValue = (int) Peak->PeakHeight;
1212 for(iSequence = 0; iSequence < Cluster->NumSequences; iSequence++)
1214 if((Cluster->SequencePad[iSequence] == Peak->pad - 1) &&
1215 (Cluster->Sequence[iSequence].startTimeBin <= Peak->Timebin) &&
1216 (Cluster->Sequence[iSequence].startTimeBin +
1217 Cluster->Sequence[iSequence].Length > Peak->Timebin))
1219 iADCMinus = Cluster->Sequence[iSequence]
1220 .FirstAdc[Peak->Timebin
1221 - Cluster->Sequence[iSequence].startTimeBin];
1223 if((Cluster->SequencePad[iSequence] == Peak->pad + 1) &&
1224 (Cluster->Sequence[iSequence].startTimeBin < Peak->Timebin) &&
1225 (Cluster->Sequence[iSequence].startTimeBin +
1226 Cluster->Sequence[iSequence].Length > Peak->Timebin))
1228 iADCPlus = Cluster->Sequence[iSequence]
1229 .FirstAdc[Peak->Timebin
1230 - Cluster->Sequence[iSequence].startTimeBin];
1235 if((iADCValue == 0) || (iADCPlus == 0) || (iADCMinus == 0) ||
1236 ((iADCValue <= iADCPlus) && (iADCValue <= iADCMinus)))
1239 iUseGauss = iUseGauss & 2;
1244 Peak->PadSigma = sqrt (1 /
1245 ((2 * fastlog[iADCValue]) -
1246 (fastlog[iADCPlus] + fastlog[iADCMinus])));
1247 Peak->PadPosition = (float) Peak->pad +
1248 sqr(Peak->PadSigma) * (fastlog[iADCPlus] - fastlog[iADCMinus]);
1252 if((iUseGauss & 1) == 0)
1255 Peak->PadPosition = (float) PadSum / (
float) ChargeSum;
1259 for(iSequence = 0; iSequence < Cluster->NumSequences; iSequence++)
1261 for(iBin = 0; iBin < Cluster->Sequence[iSequence].Length; iBin++)
1263 Peak->PadSigma+=(sqr((
float) Cluster->SequencePad[iSequence]
1264 - Peak->PadPosition)
1265 *Cluster->Sequence[iSequence].FirstAdc[iBin]);
1268 Peak->PadSigma /= (float) ChargeSum;
1272 if((iUseGauss & 2) > 0)
1275 iADCValue = (int) Peak->PeakHeight;
1279 if(Peak->Timebin > Peak->Sequence.startTimeBin)
1281 iADCMinus = Peak->Sequence.FirstAdc[Peak->Timebin -
1282 Peak->Sequence.startTimeBin - 1];
1285 if(Peak->Timebin + 1 <
1286 Peak->Sequence.startTimeBin + Peak->Sequence.Length)
1288 iADCPlus = Peak->Sequence.FirstAdc[Peak->Timebin -
1289 Peak->Sequence.startTimeBin + 1];
1293 if((iADCValue == 0) || (iADCPlus == 0) || (iADCMinus == 0) ||
1294 ((iADCValue <= iADCPlus) && (iADCValue <= iADCMinus)))
1302 Peak->TimeSigma = sqrt (1 /
1303 ((2 * fastlog[iADCValue]) -
1304 (fastlog[iADCPlus] + fastlog[iADCMinus])));
1305 Peak->TimePosition = (float) Peak->Timebin +
1306 mDb->timeOffset(iSec*mDb->numberOfPads()+Peak->pad,iRow) +
1307 sqr(Peak->TimeSigma) * (fastlog[iADCPlus] - fastlog[iADCMinus]);
1311 if((iUseGauss & 2) == 0)
1314 Peak->TimePosition = (float) TimeSum / (
float) ChargeSum;
1318 for(iSequence = 0; iSequence < Cluster->NumSequences; iSequence++)
1320 for(iBin = 0; iBin < Cluster->Sequence[iSequence].Length; iBin++)
1322 Peak->TimeSigma+=(sqr((
float)
1323 Cluster->Sequence[iSequence].startTimeBin
1324 + (
float) iBin - Peak->TimePosition)
1325 *Cluster->Sequence[iSequence].FirstAdc[iBin]);
1328 Peak->TimeSigma /= (float) ChargeSum;
1332 if(padtrans(Peak, iRow, iSec,
1333 pRadius, pDeflection))
1335 if (Peak->x == 0. && Peak->y == 0.) {
1337 LOG_WARN <<
"Hit rejected because of an error in the FTPC data. (x, y, z) = (0. ,0., z)" << endm;
1345 if(!std::isnan(Peak->x) && !std::isnan(Peak->y) && !std::isnan(Peak->PadSigma) && !std::isnan(Peak->TimeSigma))
1353 if (mhpad) mhpad->Fill(Cluster->EndPad +1 - Cluster->StartPad,1);
1354 if (mhtime) mhtime->Fill(Peak->Sequence.Length,1);
1356 Int_t numPoint = mPoint->GetEntriesFast();
1357 if (numPoint >= mPoint->GetSize()) mPoint->Expand(mPoint->GetSize()+5000);
1363 if (iRow>=10 && mDb->SwapRDO6RDO7East()) {
1366 if(iSec==3&&iRow==10){
1369 else if(iSec==3&&iRow==11){
1372 else if(iSec==3&&iRow==12){
1375 else if(iSec==3&&iRow==13){
1378 else if(iSec==3&&iRow==14){
1382 else if(iSec==3&&iRow==15){
1386 else if(iSec==3&&iRow==16){
1389 else if(iSec==3&&iRow==17) {
1392 else if(iSec==3&&iRow==18){
1395 else if(iSec==3&&iRow==19) {
1398 else if(iSec==4&&iRow==18){
1402 else if(iSec==4&&iRow==19){
1406 thispoint->SetPadRow(iRow+1);
1407 thispoint->SetSector(iSec+1);
1412 thispoint->SetPadRow(iRow+1);
1413 thispoint->SetSector(iSec+1);
1416 thispoint->SetNumberPads(Cluster->EndPad +1 - Cluster->StartPad);
1417 thispoint->SetNumberBins(Peak->Sequence.Length);
1418 thispoint->SetMaxADC((
long)Peak->PeakHeight);
1419 thispoint->SetCharge(ChargeSum);
1420 thispoint->SetPadPos(Peak->PadPosition);
1421 thispoint->SetTimePos(Peak->TimePosition);
1422 thispoint->SetPadPosSigma(Peak->PadSigma);
1423 thispoint->SetTimePosSigma(Peak->TimeSigma);
1424 thispoint->SetX(Peak->x);
1425 thispoint->SetY(Peak->y);
1426 thispoint->SetZ(Peak->z);
1427 thispoint->SetSigmaPhi(Peak->PadSigma*mDb->radiansPerPad());
1428 thispoint->SetSigmaR(Peak->TimeSigma*Peak->Rad/Peak->TimePosition);
1429 fDriftLength = mDb->sensitiveVolumeOuterRadius() - Peak->Rad;
1430 fPhiError = mParam->padDiffusionErrors(0)
1431 + fDriftLength*mParam->padDiffusionErrors(1)
1432 + fDriftLength*fDriftLength*mParam->padDiffusionErrors(2);
1433 fRadError = mParam->timeDiffusionErrors(0)
1434 + fDriftLength*mParam->timeDiffusionErrors(1)
1435 + fDriftLength*fDriftLength*mParam->timeDiffusionErrors(2);
1436 if(thispoint->GetNumberPads()==2)
1438 fPhiError = ::sqrt(fPhiError * fPhiError
1439 + sqr(mParam->twoPadWeightedError()));
1441 if((thispoint->GetNumberPads()==3) && ((iUseGauss & 1) == 1))
1443 fPhiError = ::sqrt(fPhiError * fPhiError
1444 + sqr(mParam->threePadGaussError()));
1446 if((thispoint->GetNumberPads()==3) && ((iUseGauss & 1) == 0))
1448 fPhiError = ::sqrt(fPhiError * fPhiError
1449 + sqr(mParam->threePadWeightedError()));
1452 thispoint->SetFlags(0);
1456 thispoint->SetFlags(4);
1457 fPhiError = ::sqrt(fPhiError * fPhiError
1458 + sqr(mParam->padSaturatedClusterError()));
1459 fRadError = ::sqrt(fRadError * fRadError
1460 + sqr(mParam->timeSaturatedClusterError()));
1462 if(Cluster->CutOff==1)
1464 thispoint->SetFlags(thispoint->GetFlags() | 16);
1465 fPhiError = ::sqrt(fPhiError * fPhiError
1466 + sqr(mParam->padCutoffClusterError()));
1467 fRadError = ::sqrt(fRadError * fRadError
1468 + sqr(mParam->timeCutoffClusterError()));
1471 if (Peak->Rad > mDb->sensitiveVolumeOuterRadius() ||
1472 Peak->Rad < mDb->sensitiveVolumeInnerRadius()
1476 thispoint->SetFlags(thispoint->GetFlags() | 128);
1480 PadtransBin=(int) ((Peak->TimePosition+0.5)*PadtransPerTimebin);
1481 fPhiError *= Peak->Rad / mDb->sensitiveVolumeOuterRadius();
1482 fRadError *= (pRadius[10*PadtransBin]-pRadius[10*PadtransBin+10])
1483 / (pRadius[10]-pRadius[20]);
1486 mcldebug->fillclustertree(Peak,Cluster,ChargeSum,iHardSec,iHardRow,fRadError,fPhiError,0,0,iNumPeaks);
1489 thispoint->SetXerr(::sqrt(fRadError*cos(Peak->Phi)
1490 *fRadError*cos(Peak->Phi)
1491 + fPhiError*sin(Peak->Phi)
1492 *fPhiError*sin(Peak->Phi)));
1493 thispoint->SetYerr(::sqrt(fRadError*sin(Peak->Phi)
1494 *fRadError*sin(Peak->Phi)
1495 + fPhiError*cos(Peak->Phi)
1496 *fPhiError*cos(Peak->Phi)));
1497 thispoint->SetZerr(mParam->zDirectionError());
1503 LOG_DEBUG<<
"Cluster fitting error. Point not stored"<<endm;
1509 LOG_DEBUG<<
"Peak position can't be transformed"<<endm;
1519 for(iPeakIndex=0; iPeakIndex < iNumPeaks; iPeakIndex++)
1521 Peak[iPeakIndex].TimePosition = (float) Peak[iPeakIndex].Timebin;
1522 Peak[iPeakIndex].Timebin_saved = Peak[iPeakIndex].Timebin;
1523 Peak[iPeakIndex].PadPosition = (float) Peak[iPeakIndex].pad;
1524 Peak[iPeakIndex].pad_saved = Peak[iPeakIndex].pad;
1525 Peak[iPeakIndex].OldTimePosition = 0;
1526 Peak[iPeakIndex].OldPadPosition = 0;
1527 Peak[iPeakIndex].OldPeakHeight = 0;
1528 Peak[iPeakIndex].TimeSigma = sigmat((
float) Peak[iPeakIndex].Timebin);
1529 Peak[iPeakIndex].PadSigma = sigmax((
float) Peak[iPeakIndex].Timebin);
1530 Peak[iPeakIndex].PeakHeight =
1532 .FirstAdc[Peak[iPeakIndex].Timebin
1533 - Peak[iPeakIndex].
Sequence.startTimeBin];
1545 for(iPeakIndex=0; iPeakIndex < iNumPeaks; iPeakIndex++)
1559 for(iSequence = 0; iSequence < Cluster->NumSequences; iSequence++)
1561 if((Cluster->SequencePad[iSequence]
1562 == Peak[iPeakIndex].pad) &&
1563 (Cluster->Sequence[iSequence].startTimeBin
1564 <= Peak[iPeakIndex].Timebin) &&
1565 (Cluster->Sequence[iSequence].startTimeBin +
1566 Cluster->Sequence[iSequence].Length
1567 > Peak[iPeakIndex].Timebin))
1569 iADCValue = Cluster->Sequence[iSequence]
1570 .FirstAdc[Peak[iPeakIndex].Timebin
1571 - Cluster->Sequence[iSequence].startTimeBin];
1573 if(Peak[iPeakIndex].Timebin >
1574 Cluster->Sequence[iSequence].startTimeBin)
1576 iADCTimeMinus = Cluster->Sequence[iSequence]
1577 .FirstAdc[Peak[iPeakIndex].Timebin
1578 - Cluster->Sequence[iSequence].startTimeBin - 1];
1581 if(Peak[iPeakIndex].Timebin + 1 <
1582 Cluster->Sequence[iSequence].startTimeBin
1583 + Cluster->Sequence[iSequence].Length)
1585 iADCTimePlus = Cluster->Sequence[iSequence]
1586 .FirstAdc[Peak[iPeakIndex].Timebin
1587 - Cluster->Sequence[iSequence].startTimeBin + 1];
1591 if((Cluster->SequencePad[iSequence]
1592 == Peak[iPeakIndex].pad -1) &&
1593 (Cluster->Sequence[iSequence].startTimeBin
1594 <= Peak[iPeakIndex].Timebin) &&
1595 (Cluster->Sequence[iSequence].startTimeBin +
1596 Cluster->Sequence[iSequence].Length
1597 > Peak[iPeakIndex].Timebin))
1599 iADCMinus = Cluster->Sequence[iSequence]
1600 .FirstAdc[Peak[iPeakIndex].Timebin
1601 - Cluster->Sequence[iSequence].startTimeBin];
1603 if((Cluster->SequencePad[iSequence]
1604 == Peak[iPeakIndex].pad + 1) &&
1605 (Cluster->Sequence[iSequence].startTimeBin
1606 <= Peak[iPeakIndex].Timebin) &&
1607 (Cluster->Sequence[iSequence].startTimeBin +
1608 Cluster->Sequence[iSequence].Length
1609 > Peak[iPeakIndex].Timebin))
1611 iADCPlus = Cluster->Sequence[iSequence]
1612 .FirstAdc[Peak[iPeakIndex].Timebin
1613 - Cluster->Sequence[iSequence].startTimeBin];
1622 fDeltaADCTimePlus=0;
1623 fDeltaADCTimeMinus=0;
1624 for(iInnerIndex=0; iInnerIndex < iNumPeaks; iInnerIndex++)
1626 if(iInnerIndex != iPeakIndex)
1629 if((Peak[iPeakIndex].pad == Peak[iInnerIndex].pad)
1630 && (Peak[iPeakIndex].Timebin == Peak[iInnerIndex].Timebin))
1638 fDeltaADC+=gauss_2d(Peak[iPeakIndex].pad,
1639 Peak[iPeakIndex].Timebin,
1640 Peak[iInnerIndex].PadPosition,
1641 Peak[iInnerIndex].PadSigma,
1642 Peak[iInnerIndex].TimePosition,
1643 Peak[iInnerIndex].TimeSigma,
1644 Peak[iInnerIndex].PeakHeight);
1645 fDeltaADCPlus+=gauss_2d(Peak[iPeakIndex].pad+1,
1646 Peak[iPeakIndex].Timebin,
1647 Peak[iInnerIndex].PadPosition,
1648 Peak[iInnerIndex].PadSigma,
1649 Peak[iInnerIndex].TimePosition,
1650 Peak[iInnerIndex].TimeSigma,
1651 Peak[iInnerIndex].PeakHeight);
1652 fDeltaADCMinus+=gauss_2d(Peak[iPeakIndex].pad-1,
1653 Peak[iPeakIndex].Timebin,
1654 Peak[iInnerIndex].PadPosition,
1655 Peak[iInnerIndex].PadSigma,
1656 Peak[iInnerIndex].TimePosition,
1657 Peak[iInnerIndex].TimeSigma,
1658 Peak[iInnerIndex].PeakHeight);
1659 fDeltaADCTimePlus+=gauss_2d(Peak[iPeakIndex].pad,
1660 Peak[iPeakIndex].Timebin+1,
1661 Peak[iInnerIndex].PadPosition,
1662 Peak[iInnerIndex].PadSigma,
1663 Peak[iInnerIndex].TimePosition,
1664 Peak[iInnerIndex].TimeSigma,
1665 Peak[iInnerIndex].PeakHeight);
1666 fDeltaADCTimeMinus+=gauss_2d(Peak[iPeakIndex].pad,
1667 Peak[iPeakIndex].Timebin-1,
1668 Peak[iInnerIndex].PadPosition,
1669 Peak[iInnerIndex].PadSigma,
1670 Peak[iInnerIndex].TimePosition,
1671 Peak[iInnerIndex].TimeSigma,
1672 Peak[iInnerIndex].PeakHeight);
1677 iADCValue-=(int) (fDeltaADC+0.5);
1678 iADCPlus-=(int) (fDeltaADCPlus+0.5);
1679 iADCMinus-=(int) (fDeltaADCMinus+0.5);
1680 iADCTimePlus-=(int) (fDeltaADCTimePlus+0.5);
1681 iADCTimeMinus-=(int) (fDeltaADCTimeMinus+0.5);
1686 if(iADCValue == iADCPlus)
1690 if(iADCValue == iADCMinus)
1694 if(iADCValue == iADCTimePlus)
1698 if(iADCValue == iADCTimeMinus)
1721 if(iADCTimePlus <= 0)
1726 if(iADCTimeMinus <= 0)
1740 if(iADCValue < iADCPlus)
1742 Peak[iPeakIndex].pad++;
1745 if(iADCValue < iADCMinus && PeakShifted==0)
1747 Peak[iPeakIndex].pad--;
1750 if(iADCValue < iADCTimePlus && PeakShifted==0)
1752 Peak[iPeakIndex].Timebin++;
1755 if(iADCValue < iADCTimeMinus && PeakShifted==0)
1757 Peak[iPeakIndex].Timebin--;
1761 while(PeakShifted>0 && PeakShifted<5);
1764 NewPeakHeight=iADCValue;
1766 qwe = (2 * fastlog[iADCValue]) -(fastlog[iADCPlus] + fastlog[iADCMinus]);
1767 if (qwe<=0.)
continue;
1768 Peak[iPeakIndex].PadSigma = sqrt (1 / qwe);
1769 NewPadPosition = (float) Peak[iPeakIndex].pad +
1770 sqr(Peak[iPeakIndex].PadSigma) *
1771 (fastlog[iADCPlus] - fastlog[iADCMinus]);
1772 qwe = (2 * fastlog[iADCValue]) -(fastlog[iADCTimePlus] + fastlog[iADCTimeMinus]);
1773 if (qwe<=0.)
continue;
1774 Peak[iPeakIndex].TimeSigma = sqrt (1 / qwe);
1776 NewTimePosition = (float) Peak[iPeakIndex].Timebin +
1777 mDb->timeOffset(iSec*mDb->numberOfPads()
1778 +Peak[iPeakIndex].pad,iRow) +
1779 sqr(Peak[iPeakIndex].TimeSigma) *
1780 (fastlog[iADCTimePlus] - fastlog[iADCTimeMinus]);
1783 if(iNumUnfoldLoops > MAXFASTLOOPS)
1785 NewPeakHeight=(NewPeakHeight+Peak[iPeakIndex].PeakHeight)/2;
1786 NewPadPosition=(NewPadPosition+Peak[iPeakIndex].PadPosition)/2;
1787 NewTimePosition=(NewTimePosition+Peak[iPeakIndex].TimePosition)/2;
1790 SumDeltaAmp+=fabs(NewPeakHeight - Peak[iPeakIndex].PeakHeight);
1791 Peak[iPeakIndex].OldPeakHeight=Peak[iPeakIndex].PeakHeight;
1792 Peak[iPeakIndex].PeakHeight=NewPeakHeight;
1793 SumDeltaPos+=fabs(NewPadPosition - Peak[iPeakIndex].PadPosition);
1794 Peak[iPeakIndex].OldPadPosition=Peak[iPeakIndex].PadPosition;
1795 Peak[iPeakIndex].PadPosition=NewPadPosition;
1796 SumDeltaPos+=fabs(NewTimePosition - Peak[iPeakIndex].TimePosition);
1797 Peak[iPeakIndex].OldTimePosition=Peak[iPeakIndex].TimePosition;
1798 Peak[iPeakIndex].TimePosition=NewTimePosition;
1800 PeakHeightSum+=NewPeakHeight;
1805 while((SumDeltaPos > UNFOLDLIMIT || SumDeltaAmp > 1)
1806 && (iNumUnfoldLoops < MAXLOOPS || SumDeltaPos > UNFOLDFAILEDLIMIT)
1807 && iNumUnfoldLoops < MAXLOOPS+1 && FailedFit == 0);
1810 if(SumDeltaPos > UNFOLDFAILEDLIMIT || FailedFit == 1)
1814 for(iPeakIndex=0; iPeakIndex < iNumPeaks; iPeakIndex++)
1816 Peak[iPeakIndex].TimePosition = (float) Peak[iPeakIndex].Timebin_saved;
1817 Peak[iPeakIndex].Timebin = Peak[iPeakIndex].Timebin_saved;
1818 Peak[iPeakIndex].PadPosition = (float) Peak[iPeakIndex].pad_saved;
1819 Peak[iPeakIndex].pad = Peak[iPeakIndex].pad_saved;
1820 for(iSequence = 0; iSequence < Cluster->NumSequences; iSequence++)
1822 if((Cluster->SequencePad[iSequence]
1823 == Peak[iPeakIndex].pad) &&
1824 (Cluster->Sequence[iSequence].startTimeBin
1825 <= Peak[iPeakIndex].Timebin) &&
1826 (Cluster->Sequence[iSequence].startTimeBin +
1827 Cluster->Sequence[iSequence].Length
1828 > Peak[iPeakIndex].Timebin))
1830 Peak[iPeakIndex].PeakHeight = Cluster->Sequence[iSequence]
1831 .FirstAdc[Peak[iPeakIndex].Timebin
1832 - Cluster->Sequence[iSequence].startTimeBin];
1837 LOG_DEBUG<<
"unfold failed!"<<endm;
1842 for(iPeakIndex=0; iPeakIndex < iNumPeaks; iPeakIndex++)
1845 if(padtrans(&(Peak[iPeakIndex]), iRow, iSec,
1846 pRadius, pDeflection))
1848 if (Peak[iPeakIndex].x == 0. && Peak[iPeakIndex].y == 0.) {
1850 LOG_WARN <<
"Hit rejected because of an error in the FTPC data. (x, y, z) = (0. ,0., z)" << endm;
1862 if(!std::isnan(Peak[iPeakIndex].x) && !std::isnan(Peak[iPeakIndex].y)
1863 && !std::isnan(Peak[iPeakIndex].PadSigma) && !std::isnan(Peak[iPeakIndex].TimeSigma))
1869 if (mhpad) mhpad->Fill(Cluster->EndPad +1 - Cluster->StartPad,iNumPeaks);
1870 if (mhtime) mhtime->Fill(Peak[iPeakIndex].
Sequence.Length,iNumPeaks);
1873 Int_t numPoint = mPoint->GetEntriesFast();
1874 if (numPoint >= mPoint->GetSize()) mPoint->Expand(mPoint->GetSize()+5000);
1879 if (iRow>=10 && mDb->SwapRDO6RDO7East()) {
1882 if(iSec==3&&iRow==10){
1885 else if(iSec==3&&iRow==11){
1888 else if(iSec==3&&iRow==12){
1891 else if(iSec==3&&iRow==13){
1894 else if(iSec==3&&iRow==14){
1898 else if(iSec==3&&iRow==15){
1902 else if(iSec==3&&iRow==16){
1905 else if(iSec==3&&iRow==17){
1908 else if(iSec==3&&iRow==18){
1911 else if(iSec==3&&iRow==19){
1914 else if(iSec==4&&iRow==18){
1918 else if(iSec==4&&iRow==19){
1922 thispoint->SetPadRow(iRow+1);
1923 thispoint->SetSector(iSec+1);
1928 thispoint->SetPadRow(iRow+1);
1929 thispoint->SetSector(iSec+1);
1932 thispoint->SetNumberPads(Cluster->EndPad +1 - Cluster->StartPad);
1933 thispoint->SetNumberBins(Peak[iPeakIndex].
Sequence.Length);
1934 thispoint->SetMaxADC((
long)Peak[iPeakIndex].PeakHeight);
1935 thispoint->SetCharge((Long_t)(ChargeSum*(Peak[iPeakIndex].PeakHeight
1937 thispoint->SetPadPos(Peak[iPeakIndex].PadPosition);
1938 thispoint->SetTimePos(Peak[iPeakIndex].TimePosition);
1939 thispoint->SetPadPosSigma(Peak[iPeakIndex].PadSigma);
1940 thispoint->SetTimePosSigma(Peak[iPeakIndex].TimeSigma);
1941 thispoint->SetX(Peak[iPeakIndex].x);
1942 thispoint->SetY(Peak[iPeakIndex].y);
1943 thispoint->SetZ(Peak[iPeakIndex].z);
1944 thispoint->SetSigmaPhi(Peak[iPeakIndex].PadSigma
1945 *mDb->radiansPerPad());
1946 thispoint->SetSigmaR(Peak[iPeakIndex].TimeSigma
1947 * Peak[iPeakIndex].Rad
1948 /Peak[iPeakIndex].TimePosition);
1950 fDriftLength = mDb->sensitiveVolumeOuterRadius()
1951 - Peak[iPeakIndex].Rad;
1952 fPhiError = mParam->padDiffusionErrors(0)
1953 + fDriftLength*mParam->padDiffusionErrors(1)
1954 + fDriftLength*fDriftLength*mParam->padDiffusionErrors(2);
1955 fRadError = mParam->timeDiffusionErrors(0)
1956 + fDriftLength*mParam->timeDiffusionErrors(1)
1957 + fDriftLength*fDriftLength*mParam->timeDiffusionErrors(2);
1960 thispoint->SetFlags(1);
1961 fPhiError = ::sqrt(fPhiError * fPhiError
1962 + sqr(mParam->padUnfoldError()));
1963 fRadError = ::sqrt(fRadError * fRadError
1964 + sqr(mParam->timeUnfoldError()));
1968 thispoint->SetFlags(5);
1969 fPhiError = ::sqrt(fPhiError * fPhiError
1970 + sqr(mParam->padSaturatedClusterError()));
1971 fRadError = ::sqrt(fRadError * fRadError
1972 + sqr(mParam->timeSaturatedClusterError()));
1976 thispoint->SetFlags(thispoint->GetFlags() | 8);
1977 fPhiError = ::sqrt(fPhiError * fPhiError
1978 + sqr(mParam->padBadFitError()));
1979 fRadError = ::sqrt(fRadError * fRadError
1980 + sqr(mParam->timeBadFitError()));
1982 if(iNumUnfoldLoops == MAXLOOPS)
1984 thispoint->SetFlags(thispoint->GetFlags() | 10);
1985 fPhiError = ::sqrt(fPhiError * fPhiError
1986 + sqr(mParam->padFailedFitError()));
1987 fRadError = ::sqrt(fRadError * fRadError
1988 + sqr(mParam->timeFailedFitError()));
1990 if(Cluster->CutOff==1)
1992 thispoint->SetFlags(thispoint->GetFlags() | 16);
1993 fPhiError = ::sqrt(fPhiError * fPhiError
1994 + sqr(mParam->padCutoffClusterError()));
1995 fRadError = ::sqrt(fRadError * fRadError
1996 + sqr(mParam->timeCutoffClusterError()));
1999 if (Peak[iPeakIndex].Rad > mDb->sensitiveVolumeOuterRadius() ||
2000 Peak[iPeakIndex].Rad < mDb->sensitiveVolumeInnerRadius()
2004 thispoint->SetFlags(thispoint->GetFlags() | 128);
2008 PadtransBin=(int) ((Peak->TimePosition+0.5)*PadtransPerTimebin);
2009 fPhiError *= Peak->Rad / mDb->sensitiveVolumeOuterRadius();
2010 fRadError *= (pRadius[10*PadtransBin]-pRadius[10*PadtransBin+10])
2011 / (pRadius[10]-pRadius[20]);
2014 mcldebug->fillclustertree(Peak[iPeakIndex],Cluster,ChargeSum*Peak[iPeakIndex].PeakHeight/PeakHeightSum,iHardSec,iHardRow,fRadError,fPhiError,10,0,iNumPeaks);
2017 thispoint->SetXerr(::sqrt(fRadError*cos(Peak[iPeakIndex].Phi)
2018 *fRadError*cos(Peak[iPeakIndex].Phi)
2019 + fPhiError*sin(Peak[iPeakIndex].Phi)
2020 *fPhiError*sin(Peak[iPeakIndex].Phi)));
2021 thispoint->SetYerr(::sqrt(fRadError*sin(Peak[iPeakIndex].Phi)
2022 *fRadError*sin(Peak[iPeakIndex].Phi)
2023 + fPhiError*cos(Peak[iPeakIndex].Phi)
2024 *fPhiError*cos(Peak[iPeakIndex].Phi)));
2025 thispoint->SetZerr(mParam->zDirectionError());
2032 LOG_DEBUG<<
"Peak position can't be transformed!"<<endm;
2040 int StFtpcClusterFinder::padtrans(
TPeak *Peak,
2044 double *pDeflection)
2046 int PadtransPerTimebin;
2048 float PhiDeflect, TimeCoordinate;
2050 if (iRow>=10 && mDb->SwapRDO6RDO7East()) {
2051 if(iSec==3&&iRow==10) {
2054 else if(iSec==3&&iRow==11) {
2057 else if(iSec==3&&iRow==12) {
2060 else if(iSec==3&&iRow==13) {
2063 else if(iSec==3&&iRow==14) {
2067 else if(iSec==3&&iRow==15) {
2071 else if(iSec==3&&iRow==16) {
2074 else if(iSec==3&&iRow==17) {
2077 else if(iSec==3&&iRow==18) {
2080 else if(iSec==3&&iRow==19) {
2083 else if(iSec==4&&iRow==18) {
2087 else if(iSec==4&&iRow==19) {
2094 TimeCoordinate = Peak->TimePosition + 0.5;
2096 TimeCoordinate += mDb->tZero()/mDb->microsecondsPerTimebin();
2097 PadtransPerTimebin = (int) mParam->numberOfDriftSteps() / mDb->numberOfTimebins();
2098 PadtransLower= (int) (TimeCoordinate*PadtransPerTimebin);
2100 if ( TimeCoordinate > mDb->numberOfTimebins() || TimeCoordinate <= 0 )
2107 Peak->Rad=pRadius[iRow + mDb->numberOfPadrowsPerSide() * PadtransLower]
2108 -(pRadius[iRow + mDb->numberOfPadrowsPerSide()*(PadtransLower)]
2109 -pRadius[iRow + mDb->numberOfPadrowsPerSide() * (PadtransLower+1)])/2;
2111 if ( pRadius[iRow + mDb->numberOfPadrowsPerSide() * PadtransLower] == 0 )
2118 PhiDeflect=pDeflection[iRow + mDb->numberOfPadrowsPerSide() * PadtransLower]
2119 +(pDeflection[iRow + mDb->numberOfPadrowsPerSide() * (PadtransLower+1)]
2120 -pDeflection[iRow + mDb->numberOfPadrowsPerSide() * PadtransLower])/2;
2126 Peak->Phi = mDb->radiansPerBoundary() / 2
2127 + ((Peak->PadPosition-1) + 0.5) * mDb->radiansPerPad()
2128 + PhiDeflect + iSec * (mDb->numberOfPads() * mDb->radiansPerPad()
2129 + mDb->radiansPerBoundary())+halfpi;
2135 Peak->Phi = mDb->radiansPerBoundary() / 2
2136 + (159.5 - (Peak->PadPosition-1))* mDb->radiansPerPad()
2137 - PhiDeflect + iSec * (mDb->numberOfPads() * mDb->radiansPerPad()
2138 + mDb->radiansPerBoundary())+halfpi;
2145 if (fabs(mOffsetCathodeWest)>0 || fabs(mOffsetCathodeEast)>0)
2149 TimeCoordinate=(0.999997-0.09739494018294076*mOffsetCathodeWest*cos(Peak->Phi-mAngleOffsetWest))*TimeCoordinate;
2152 TimeCoordinate=(0.999997-0.09739494018294076*mOffsetCathodeEast*sin(Peak->Phi+mAngleOffsetEast))*TimeCoordinate;
2159 PadtransLower= (int) (TimeCoordinate*PadtransPerTimebin);
2161 if ( TimeCoordinate > mDb->numberOfTimebins() || TimeCoordinate <= 0 )
2169 Peak->Rad=pRadius[iRow + mDb->numberOfPadrowsPerSide() * PadtransLower]
2170 -(pRadius[iRow + mDb->numberOfPadrowsPerSide()*(PadtransLower)]
2171 -pRadius[iRow + mDb->numberOfPadrowsPerSide() * (PadtransLower+1)])/2;
2173 if ( pRadius[iRow + mDb->numberOfPadrowsPerSide() * PadtransLower] == 0 )
2182 PhiDeflect=pDeflection[iRow + mDb->numberOfPadrowsPerSide() * PadtransLower]
2183 +(pDeflection[iRow + mDb->numberOfPadrowsPerSide() * (PadtransLower+1)]
2184 -pDeflection[iRow + mDb->numberOfPadrowsPerSide() * PadtransLower])/2;
2190 Peak->Phi = mDb->radiansPerBoundary() / 2
2191 + ((Peak->PadPosition-1) + 0.5) * mDb->radiansPerPad()
2192 + PhiDeflect + iSec * (mDb->numberOfPads() * mDb->radiansPerPad()
2193 + mDb->radiansPerBoundary())+halfpi;
2199 Peak->Phi = mDb->radiansPerBoundary() / 2
2200 + (159.5 - (Peak->PadPosition-1))* mDb->radiansPerPad()
2201 - PhiDeflect + iSec * (mDb->numberOfPads() * mDb->radiansPerPad()
2202 + mDb->radiansPerBoundary())+halfpi;
2209 Peak->x = Peak->Rad*cos(Peak->Phi);
2214 Peak->y = Peak->Rad*sin(Peak->Phi);
2215 Peak->z = mDb->padrowZPosition(iRow);
2219 float StFtpcClusterFinder::gauss_2d(
int x,
int y,
float x1,
float sigma_x1,
float y1,
float sigma_y1,
float amp1)
2224 if(sigma_x1==0 || sigma_y1==0)
2229 g1=exp(-sqr((
float)x-x1)/(2*sqr(sigma_x1)));
2230 g2=exp(-sqr((
float)y-y1)/(2*sqr(sigma_y1)));
2237 float StFtpcClusterFinder::sigmax(
float timebin)
2242 float StFtpcClusterFinder::sigmat(
float timebin)
2247 int StFtpcClusterFinder::calcpadtrans(
double *pradius,
2248 double *pdeflection,
double deltap)
2250 int i, j, v_buf, padrow;
2251 double t_last, t_next, r_last, r_next, e_now, v_now, psi_now;
2254 step_size=((float) mDb->numberOfTimebins()
2255 / (float) mParam->numberOfDriftSteps());
2257 LOG_DEBUG <<
"StFtpcClusterFinder::calcpadtrans deltap = "<<deltap<<endm;
2259 for (padrow=0; padrow<mDb->numberOfPadrowsPerSide(); padrow++)
2264 r_last=mDb->sensitiveVolumeOuterRadius();
2265 pradius[padrow]=mDb->sensitiveVolumeOuterRadius();
2266 pdeflection[padrow]=0;
2267 e_now = mDb->radiusTimesField() / (0.5*r_last);
2268 for(j=v_buf; j<mDb->numberOfMagboltzBins()-1
2269 && mDb->magboltzEField(j) < e_now; j++);
2270 if(j<1 || j>mDb->numberOfMagboltzBins())
2272 LOG_ERROR <<
"calcpadtrans error 1: j=" << j <<
", v_buf=" << v_buf <<
" e_drift=" << mDb->magboltzEField(j) <<
", e_now=" << e_now << endm;
2276 v_now=((mDb->magboltzVDrift(v_buf, padrow)
2277 +deltap*mDb->magboltzdVDriftdP(v_buf, padrow))
2278 *(mDb->magboltzEField(j)-e_now)
2279 +(mDb->magboltzVDrift(j, padrow)
2280 +deltap*mDb->magboltzdVDriftdP(j, padrow))
2281 *(e_now-mDb->magboltzEField(v_buf)))
2282 /(mDb->magboltzEField(j)-mDb->magboltzEField(v_buf));
2283 psi_now=((mDb->magboltzDeflection(v_buf,padrow)
2284 +deltap*mDb->magboltzdDeflectiondP(v_buf,padrow))
2285 *mParam->lorentzAngleFactor()
2286 *(mDb->magboltzEField(j)-e_now)
2287 +(mDb->magboltzDeflection(j,padrow)
2288 +deltap*mDb->magboltzdDeflectiondP(j,padrow))
2289 *mParam->lorentzAngleFactor()
2290 *(e_now-mDb->magboltzEField(v_buf)))
2291 /(mDb->magboltzEField(j)-mDb->magboltzEField(v_buf));
2292 for (i=0; i<mParam->numberOfDriftSteps()-1
2293 && e_now < mDb->magboltzEField(mDb->numberOfMagboltzBins()-2)
2296 t_next = t_last + step_size;
2298 r_next = r_last - v_now * step_size * mDb->microsecondsPerTimebin();
2299 e_now = mDb->radiusTimesField() / (0.5*(r_last+r_next));
2301 for(j=v_buf; j<mDb->numberOfMagboltzBins()-1
2302 && mDb->magboltzEField(j) < e_now; j++);
2304 if(j<1 || j>mDb->numberOfMagboltzBins())
2306 LOG_ERROR <<
"calcpadtrans error 2: j=" << j <<
", v_buf=" << v_buf <<
" e_drift=" << mDb->magboltzEField(j) <<
", e_now=" << e_now << endm;
2311 v_now=((mDb->magboltzVDrift(v_buf, padrow)
2312 +deltap*mDb->magboltzdVDriftdP(v_buf, padrow))
2313 *(mDb->magboltzEField(j)-e_now)
2314 +(mDb->magboltzVDrift(j, padrow)
2315 +deltap*mDb->magboltzdVDriftdP(j, padrow))
2316 *(e_now-mDb->magboltzEField(v_buf)))
2317 /(mDb->magboltzEField(j)-mDb->magboltzEField(v_buf));
2318 psi_now=((mDb->magboltzDeflection(v_buf,padrow)
2319 +deltap*mDb->magboltzdDeflectiondP(v_buf,padrow))
2320 *mParam->lorentzAngleFactor()
2321 *(mDb->magboltzEField(j)-e_now)
2322 +(mDb->magboltzDeflection(j,padrow)
2323 +deltap*mDb->magboltzdDeflectiondP(j,padrow))
2324 *mParam->lorentzAngleFactor()
2325 *(e_now-mDb->magboltzEField(v_buf)))
2326 /(mDb->magboltzEField(j)-mDb->magboltzEField(v_buf));
2329 r_next = r_last - v_now * step_size *mDb->microsecondsPerTimebin();
2330 pradius[padrow+mDb->numberOfPadrowsPerSide()*(i+1)]=r_next;
2331 pdeflection[padrow+mDb->numberOfPadrowsPerSide()*(i+1)]
2332 =pdeflection[padrow+mDb->numberOfPadrowsPerSide()*i]
2333 +((r_last-r_next)*tan(degree * psi_now)/r_last);
2338 LOG_DEBUG<<i<<
" steps calculated, padrow "<<padrow<<endm;
2344 int StFtpcClusterFinder::cucInit(
TClusterUC memory[MAXNUMCUC],
int RealMemory[MAXNUMCUC],
int *pointer)
2348 for(i=0; i<MAXNUMCUC; i++)
2356 TClusterUC *StFtpcClusterFinder::cucAlloc(
TClusterUC memory[MAXNUMCUC],
int RealMemory[MAXNUMCUC],
int *pointer)
2359 if((*pointer)+1 < MAXNUMCUC)
2362 memory[RealMemory[*pointer]].MemoryPtr = RealMemory[*pointer];
2363 return &memory[RealMemory[*pointer]];
2368 LOG_DEBUG<<
"CUC memory exhausted! requested "<<*pointer<<
" CUCs"<<endm;
2374 int StFtpcClusterFinder::cucFree(
TClusterUC memory[MAXNUMCUC],
int RealMemory[MAXNUMCUC],
int *pointer,
TClusterUC *OldCUC)
2378 RealMemory[*pointer] = OldCUC->MemoryPtr;
2385 LOG_DEBUG<<
"CUC memory management confused!"<<endm;