default parameters are set for the clusterfinder
[u/mrichter/AliRoot.git] / HLT / TPCLib / HWCFemulator / AliHLTTPCHWCFMergerUnit.cxx
1 // $Id$
2 //****************************************************************************
3 //* This file is property of and copyright by the ALICE HLT Project          * 
4 //* ALICE Experiment at CERN, All rights reserved.                           *
5 //*                                                                          *
6 //* Primary Authors: Sergey Gorbunov, Torsten Alt                            *
7 //* Developers:      Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de> *
8 //*                  Torsten Alt <talt@cern.ch>                              *
9 //*                  for The ALICE HLT Project.                              *
10 //*                                                                          *
11 //* Permission to use, copy, modify and distribute this software and its     *
12 //* documentation strictly for non-commercial purposes is hereby granted     *
13 //* without fee, provided that the above copyright notice appears in all     *
14 //* copies and that both the copyright notice and this permission notice     *
15 //* appear in the supporting documentation. The authors make no claims       *
16 //* about the suitability of this software for any purpose. It is            *
17 //* provided "as is" without express or implied warranty.                    *
18 //****************************************************************************
19
20 //  @file   AliHLTTPCHWCFMergerUnit.cxx
21 //  @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de>
22 //  @author Torsten Alt <talt@cern.ch> 
23 //  @date   
24 //  @brief  Channel Merger unit of FPGA ClusterFinder Emulator for TPC
25 //  @brief  ( see AliHLTTPCHWCFEmulator class )
26 //  @note 
27
28 #include "AliHLTTPCHWCFMergerUnit.h"
29 #include <iostream>
30
31 AliHLTTPCHWCFMergerUnit::AliHLTTPCHWCFMergerUnit()
32   :
33   fDebug(0),
34   fMatchDistance(0),
35   fMatchTimeFollow(0),
36   fDeconvolute(0),
37   fByPassMerger(0),
38   fInput()
39 {
40   //constructor 
41   Init();
42 }
43
44
45 AliHLTTPCHWCFMergerUnit::~AliHLTTPCHWCFMergerUnit()
46 {   
47   //destructor 
48 }
49
50 AliHLTTPCHWCFMergerUnit::AliHLTTPCHWCFMergerUnit(const AliHLTTPCHWCFMergerUnit&)
51   :
52   fDebug(0),
53   fMatchDistance(0),
54   fMatchTimeFollow(0),
55   fDeconvolute(0),
56   fByPassMerger(0),
57   fInput()
58 {
59   // dummy
60   Init();
61 }
62
63 AliHLTTPCHWCFMergerUnit& AliHLTTPCHWCFMergerUnit::operator=(const AliHLTTPCHWCFMergerUnit&)
64 {
65   // dummy  
66   return *this;
67 }
68
69 int AliHLTTPCHWCFMergerUnit::Init()
70 {
71   // initialise 
72
73   fInput.fFlag = 0;
74   for( int i=0; i<2; i++ ){
75     fSearchRange[i] = fMemory[i];
76     fInsertRange[i] = (fMemory[i]+AliHLTTPCHWCFDefinitions::kMaxNTimeBins);
77     fSearchStart[i] = 0;
78     fSearchEnd[i] = 0;
79     fInsertEnd[i] = 0;
80     fInsertRow[i] = -1;
81     fInsertPad[i] = -1;
82   }    
83   return 0;
84 }
85
86 int AliHLTTPCHWCFMergerUnit::InputStream( const AliHLTTPCHWCFClusterFragment *fragment )
87 {
88   // input stream of data 
89
90   fInput.fFlag = 0;
91
92   if( fragment ){
93     fInput = *fragment;
94     fInput.fSlope = 0;
95     fInput.fLastQ = fInput.fQ;
96     if( fDebug ){
97       std::cout<<"Merger: input Br: "<<fragment->fBranch<<" F: "<<fragment->fFlag<<" R: "<<fragment->fRow
98                <<" Q: "<<(fragment->fQ>>AliHLTTPCHWCFDefinitions::kFixedPoint)
99                <<" P: "<<fragment->fPad<<" Tmean: "<<fragment->fTMean;          
100       if( fragment->fFlag==1 && fragment->fQ > 0 ){
101         std::cout<<" Pw: "<<((float)fragment->fP)/fragment->fQ
102                  <<" Tw: "<<((float)fragment->fT)/fragment->fQ;
103         std::cout<<"   MC: ";
104         for( unsigned int j=0; j<fragment->fMC.size(); j++ ){
105           for( int k=0; k<3; k++ ){
106             std::cout<<"("<<fragment->fMC[j].fClusterID[k].fMCID<<" "<<fragment->fMC[j].fClusterID[k].fWeight<<") ";
107           }
108         }
109         std::cout<<std::endl;
110       }
111       else std::cout<<std::endl;      
112     }
113   }
114   return 0;
115 }
116
117 const AliHLTTPCHWCFClusterFragment *AliHLTTPCHWCFMergerUnit::OutputStream()
118 {
119   // output stream of data 
120
121   if( fInput.fFlag==0 ) return 0;
122
123   if( fByPassMerger ){
124     fInsertRange[0][0] = fInput;
125     fInput.fFlag = 0;
126     return &fInsertRange[0][0];
127   }
128
129   if( fInput.fFlag!=1 ){
130
131     for( int ib=0; ib<2; ib++){
132       
133       // move insert range to search range
134       
135       if( fSearchStart[ib]>=fSearchEnd[ib] && fInsertEnd[ib]>0 ){       
136         AliHLTTPCHWCFClusterFragment *tmp = fSearchRange[ib];
137         fSearchRange[ib] = fInsertRange[ib];
138         fSearchStart[ib] = 0;
139         fSearchEnd[ib] = fInsertEnd[ib];
140         fInsertRange[ib] = tmp;
141         fInsertEnd[ib] = 0;
142         fInsertPad[ib]++;
143       }    
144
145       // flush the search range
146   
147       if( fSearchStart[ib]<fSearchEnd[ib] ){
148       fSearchStart[ib]++;
149       return &(fSearchRange[ib][fSearchStart[ib]-1]);
150       }    
151     
152       fInsertRow[ib] = -1;
153       fInsertPad[ib] = -1;
154     }
155     
156     fInsertRange[0][0] = fInput; // forward the input
157     fInput.fFlag = 0;
158     return &fInsertRange[0][0];  
159   }
160
161   if( fInput.fFlag!=1 ) return 0; // should not happen
162
163   int ib = fInput.fBranch;
164   
165   // move insert range to search range
166     
167   if( (int)fInput.fRow!=fInsertRow[ib] || (int)fInput.fPad!=fInsertPad[ib] ){
168     
169     if( fSearchStart[ib]>=fSearchEnd[ib] && fInsertEnd[ib]>0 ){
170       // cout<<"move insert range pad "<<fInsertPad[ib]<<endl;
171       AliHLTTPCHWCFClusterFragment *tmp = fSearchRange[ib];
172       fSearchRange[ib] = fInsertRange[ib];
173       fSearchStart[ib] = 0;
174       fSearchEnd[ib] = fInsertEnd[ib];
175       fInsertRange[ib] = tmp;
176       fInsertEnd[ib] = 0;
177       fInsertPad[ib]++;
178     }
179   }
180
181   // flush the search range
182   
183   if( (int)fInput.fRow!=fInsertRow[ib] || (int)fInput.fPad!=fInsertPad[ib] ){
184     if( fSearchStart[ib]<fSearchEnd[ib] ){
185       //cout<<"push from search range at "<<fSearchStart[ib]<<" of "<<fSearchEnd[ib]<<endl;
186       fSearchStart[ib]++;
187       return &(fSearchRange[ib][fSearchStart[ib]-1]);
188     }
189   }
190     
191   fInsertRow[ib] = fInput.fRow;
192   fInsertPad[ib] = fInput.fPad;
193   
194   // flush the search range
195   
196   if( fSearchStart[ib]<fSearchEnd[ib]  && fSearchRange[ib][fSearchStart[ib]].fTMean>=fInput.fTMean+fMatchDistance
197       ){
198     //cout<<"push from search range at "<<fSearchStart[ib]<<" of "<<fSearchEnd[ib]<<endl;
199     fSearchStart[ib]++;
200     return &(fSearchRange[ib][fSearchStart[ib]-1]);
201   }
202
203   // merge 
204   
205   AliHLTTPCHWCFClusterFragment *ret = 0;
206   
207   if( fSearchStart[ib]<fSearchEnd[ib]  && fSearchRange[ib][fSearchStart[ib]].fTMean+fMatchDistance>fInput.fTMean ){
208     AliHLTTPCHWCFClusterFragment &s = fSearchRange[ib][fSearchStart[ib]++];
209     if( fDeconvolute && s.fSlope && s.fLastQ<fInput.fLastQ ){
210       //cout<<"push from search range at "<<fSearchStart[ib]-1<<" of "<<fSearchEnd[ib]<<endl;
211       ret = &s;
212     } else {
213       // cout<<"merge search range at "<<fSearchStart-1<<" of "<<fSearchEnd<<endl;
214       if( !fInput.fSlope && s.fLastQ > fInput.fQ ) fInput.fSlope = 1;
215       if (fInput.fQmax < s.fQmax) fInput.fQmax = s.fQmax;
216       fInput.fQ += s.fQ;
217       fInput.fT += s.fT;
218       fInput.fT2 += s.fT2;
219       fInput.fP += s.fP;
220       fInput.fP2 += s.fP2;
221       fInput.fMC.insert(fInput.fMC.end(), s.fMC.begin(), s.fMC.end());
222       if( !fMatchTimeFollow ) fInput.fTMean = s.fTMean;    
223       ret = 0;
224     }
225   }
226   
227   // insert 
228   
229   fInsertRange[ib][fInsertEnd[ib]++] = fInput;
230   fInput.fFlag = 0;
231   return ret;
232 }