Line data Source code
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 AliHLTTPCHWCFDivisionUnit.cxx
21 : // @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de>
22 : // @author Torsten Alt <talt@cern.ch>
23 : // @date
24 : // @brief Division unit of FPGA ClusterFinder Emulator for TPC
25 : // @brief ( see AliHLTTPCHWCFEmulator class )
26 : // @note
27 :
28 : #include "AliHLTTPCHWCFDivisionUnit.h"
29 : #include "AliHLTErrorGuard.h"
30 : #include "TNtuple.h"
31 : #include "TFile.h"
32 : #include <iostream>
33 : #include <algorithm>
34 :
35 :
36 3 : AliHLTTPCHWCFDivisionUnit::AliHLTTPCHWCFDivisionUnit()
37 : :
38 6 : fSinglePadSuppression(1), fClusterLowerLimit(0), fTagDeconvolutedClusters(0), fkInput(0),fOutput(), fDebug(0), fDebugNtuple(0),fDebugFile(0)
39 15 : {
40 : //constructor
41 6 : }
42 :
43 :
44 : AliHLTTPCHWCFDivisionUnit::~AliHLTTPCHWCFDivisionUnit()
45 12 : {
46 3 : if( fDebugNtuple ) fDebugNtuple->Write();
47 3 : if( fDebugFile ){
48 0 : fDebugFile->Write();
49 0 : fDebugFile->Close();
50 : }
51 : //destructor
52 6 : }
53 :
54 0 : AliHLTTPCHWCFDivisionUnit::AliHLTTPCHWCFDivisionUnit(const AliHLTTPCHWCFDivisionUnit&)
55 : :
56 0 : fSinglePadSuppression(1),fClusterLowerLimit(0),fTagDeconvolutedClusters(0), fkInput(0),fOutput(), fDebug(0), fDebugNtuple(0), fDebugFile(0)
57 0 : {
58 0 : }
59 :
60 :
61 : AliHLTTPCHWCFDivisionUnit& AliHLTTPCHWCFDivisionUnit::operator=(const AliHLTTPCHWCFDivisionUnit&)
62 : {
63 : // dummy
64 0 : return *this;
65 : }
66 :
67 : int AliHLTTPCHWCFDivisionUnit::Init()
68 : {
69 : // initialise
70 0 : fkInput = 0;
71 0 : return 0;
72 : }
73 :
74 :
75 : int AliHLTTPCHWCFDivisionUnit::InputStream( const AliHLTTPCHWCFClusterFragment *fragment )
76 : {
77 : // input stream of data
78 0 : fkInput = fragment;
79 0 : if( fkInput && fDebug==1 ){
80 0 : std::cout<<"HWCF Division: input Br: "<<fragment->fBranch<<" F: "<<fragment->fFlag<<" R: "<<fragment->fRow
81 0 : <<" Q: "<<(fragment->fQ>>AliHLTTPCHWCFDefinitions::kFixedPoint)
82 0 : <<" P: "<<fragment->fPad<<" Tmean: "<<fragment->fTMean;
83 0 : if( fragment->fFlag==1 && fragment->fQ > 0 ){
84 0 : std::cout<<" Pw: "<<((float)fragment->fP)/fragment->fQ
85 0 : <<" Tw: "<<((float)fragment->fT)/fragment->fQ;
86 0 : std::cout<<" MC: ";
87 0 : for( unsigned int j=0; j<fragment->fMC.size(); j++ ){
88 0 : for( int k=0; k<3; k++ ){
89 0 : std::cout<<"("<<fragment->fMC[j].fClusterID[k].fMCID<<" "<<fragment->fMC[j].fClusterID[k].fWeight<<") ";
90 : }
91 : }
92 0 : std::cout<<std::endl;
93 0 : }
94 0 : else std::cout<<std::endl;
95 : }
96 :
97 0 : return 0;
98 : }
99 :
100 : const AliHLTTPCHWCFCluster *AliHLTTPCHWCFDivisionUnit::OutputStream()
101 : {
102 : // output stream of data
103 :
104 0 : if( !fkInput ) return 0;
105 :
106 0 : if( fkInput->fFlag==2 ){ // RCU trailer word
107 0 : fOutput.fFlag = 2;
108 0 : fOutput.fRowQ = fkInput->fRow; // rcu word
109 0 : fkInput = 0;
110 0 : return &fOutput;;
111 : }
112 :
113 0 : if( fkInput->fFlag!=1 ) return 0;
114 :
115 0 : if( fkInput->fQ==0 ) return 0;
116 0 : if( fSinglePadSuppression && fkInput->fQ==fkInput->fLastQ && !fkInput->fBorder ) return 0;
117 0 : if( fkInput->fQ < fClusterLowerLimit ) return 0;
118 :
119 0 : AliHLTFloat32_t q = fkInput->fQ;
120 :
121 0 : fOutput.fFlag = 1;
122 :
123 : // bit 23 is 0, bits 30,31 are 1
124 0 : fOutput.fRowQ = (((AliHLTUInt32_t) 0x3)<<30) + ((fkInput->fRow &0x3f)<<24) + ((fkInput->fQmax)&0x7FFFFF);
125 :
126 : // bits 30,31 are 0
127 0 : fOutput.fQ = fkInput->fQ & 0x3FFFFFFF;
128 :
129 : // set is_deconvoluted flag at bit 31 for pad direction, at bit 30 for time direction
130 :
131 0 : switch( fTagDeconvolutedClusters ){
132 : case 0:
133 : break;
134 : case 1:
135 0 : if( fkInput->fIsDeconvolutedPad ) fOutput.fQ += (0x1 << 31 );
136 0 : if( fkInput->fNDeconvolutedTime>0 ) fOutput.fQ += (0x1 << 30 );
137 : break;
138 : case 2:
139 0 : if( fkInput->fIsDeconvolutedPad ) fOutput.fQ += (0x1 << 31 );
140 0 : if( fkInput->fNPads>1 ){
141 0 : if( fkInput->fConsecutiveTimeDeconvolution>=2 ) fOutput.fQ += (0x1 << 30 );
142 : } else {
143 0 : if( fkInput->fNDeconvolutedTime>0 ) fOutput.fQ += (0x1 << 30 );
144 : }
145 : break;
146 : default:
147 0 : HLTError("Unknown HW cluster tagging option %d",fTagDeconvolutedClusters);
148 : }
149 :
150 0 : *((AliHLTFloat32_t*)&fOutput.fP) = (float)fkInput->fP/q;
151 0 : *((AliHLTFloat32_t*)&fOutput.fT) = (float)fkInput->fT/q;
152 0 : *((AliHLTFloat32_t*)&fOutput.fP2) = (float)fkInput->fP2/q;
153 0 : *((AliHLTFloat32_t*)&fOutput.fT2) = (float)fkInput->fT2/q;
154 :
155 : // MC part
156 :
157 0 : AliHLTTPCClusterMCWeight emptyWeight;
158 :
159 0 : fOutput.fMC.fClusterID[0] = emptyWeight;
160 0 : fOutput.fMC.fClusterID[1] = emptyWeight;
161 0 : fOutput.fMC.fClusterID[2] = emptyWeight;
162 :
163 0 : vector<AliHLTTPCClusterMCWeight> labels;
164 0 : for( unsigned i=0; i<fkInput->fMC.size(); i++){
165 0 : labels.push_back(fkInput->fMC[i].fClusterID[0]);
166 0 : labels.push_back(fkInput->fMC[i].fClusterID[1]);
167 0 : labels.push_back(fkInput->fMC[i].fClusterID[2]);
168 : }
169 0 : sort(labels.begin(), labels.end(), CompareMCLabels);
170 0 : for( unsigned int i=1; i<labels.size(); i++ ){
171 0 : if(labels[i-1].fMCID==labels[i].fMCID ){
172 0 : labels[i].fWeight+=labels[i-1].fWeight;
173 0 : labels[i-1].fWeight = 0;
174 0 : }
175 : }
176 :
177 0 : sort(labels.begin(), labels.end(), CompareMCWeights );
178 :
179 0 : for( unsigned int i=0; i<3 && i<labels.size(); i++ ){
180 0 : if( labels[i].fMCID <0 ) continue;
181 0 : fOutput.fMC.fClusterID[i] = labels[i];
182 0 : }
183 :
184 0 : if( fDebug==2 ){
185 0 : if( !fDebugNtuple ){
186 0 : cout<<"HW clusterfinder emulator: Create cluster debug file 'HWClustersDebug.root' .."<<endl;
187 0 : fDebugFile = new TFile("HWClustersDebug.root","RECREATE");
188 0 : fDebugFile->cd();
189 0 : fDebugNtuple = new TNtuple("HWClusters", "HWClusters", "iNPads:iIsSplitPad:iNSplitTime:iIsConsSplitTime");
190 0 : if( fDebugNtuple ) fDebugNtuple->AutoSave();
191 : }
192 0 : if( fDebugNtuple ){
193 0 : fDebugNtuple->Fill(fkInput->fNPads, fkInput->fIsDeconvolutedPad, fkInput->fNDeconvolutedTime, (fkInput->fConsecutiveTimeDeconvolution>=2));
194 : }
195 : }
196 :
197 0 : fkInput = 0;
198 :
199 : return &fOutput;
200 0 : }
201 :
|