]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCAgent.cxx
adjusting the configuration of TPC data compression and monitoring to what is being...
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCAgent.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project        * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8 //*                  for The ALICE HLT Project.                            *
9 //*                                                                        *
10 //* Permission to use, copy, modify and distribute this software and its   *
11 //* documentation strictly for non-commercial purposes is hereby granted   *
12 //* without fee, provided that the above copyright notice appears in all   *
13 //* copies and that both the copyright notice and this permission notice   *
14 //* appear in the supporting documentation. The authors make no claims     *
15 //* about the suitability of this software for any purpose. It is          *
16 //* provided "as is" without express or implied warranty.                  *
17 //**************************************************************************
18
19 //  @file   AliHLTTPCAgent.cxx
20 //  @author Matthias Richter
21 //  @date   
22 //  @brief  Agent of the libAliHLTTPC library
23 //  @note   
24
25 #include "AliHLTTPCAgent.h"
26 #include "AliHLTTPCDefinitions.h"
27 #include "AliHLTOUT.h"
28 #include "AliHLTOUTHandlerChain.h"
29 #include "AliRunLoader.h"
30 #include "AliCDBManager.h"
31 #include "AliCDBEntry.h"
32 #include "AliTPCParam.h"
33
34 /** global instance for agent registration */
35 AliHLTTPCAgent gAliHLTTPCAgent;
36
37 // component headers
38 #include "AliHLTTPCCompModelInflaterComponent.h"
39 #include "AliHLTTPCCompModelDeflaterComponent.h"
40 #include "AliHLTTPCCompModelDeconverterComponent.h"
41 #include "AliHLTTPCCompModelConverterComponent.h"
42 #include "AliHLTTPCCompDumpComponent.h"
43 //#include "AliHLTTPCCalibCEComponent.h"
44 //#include "AliHLTTPCCalibPulserComponent.h"
45 //#include "AliHLTTPCCalibPedestalComponent.h"
46 #include "AliHLTTPCCAInputDataCompressorComponent.h"
47 #include "AliHLTTPCCATrackerComponent.h"
48 #include "AliHLTTPCCATrackerOutputConverter.h"
49 #include "AliHLTTPCTrackMCMarkerComponent.h"
50 #include "AliHLTTPCCAGlobalMergerComponent.h"
51 #include "AliHLTTPCdEdxComponent.h"
52 #include "AliHLTTPCdEdxMonitoringComponent.h"
53 #include "AliHLTTPCGlobalMergerComponent.h"
54 #include "AliHLTTPCSliceTrackerComponent.h"
55 #include "AliHLTTPCClusterFinderComponent.h"
56 #include "AliHLTTPCRawDataUnpackerComponent.h"
57 #include "AliHLTTPCDigitPublisherComponent.h"
58 #include "AliHLTTPCDigitDumpComponent.h"
59 #include "AliHLTTPCClusterDumpComponent.h"
60 #include "AliHLTTPCEsdWriterComponent.h"
61 #include "AliHLTTPCOfflineClustererComponent.h"
62 #include "AliHLTTPCOfflineTrackerComponent.h"
63 #include "AliHLTTPCOfflineTrackerCalibComponent.h"
64 #include "AliHLTTPCOfflineCalibrationComponent.h" // to be added to the calibration library agent
65 #include "AliHLTTPCClusterHistoComponent.h"
66 #include "AliHLTTPCHistogramHandlerComponent.h"
67 //#include "AliHLTTPCCalibTracksComponent.h"
68 #include "AliHLTTPCTrackHistoComponent.h"
69 #include "AliHLTTPCTrackDumpComponent.h"
70 #include "AliHLTTPCHWCFDataReverterComponent.h"
71 #include "AliHLTTPCHWClusterTransformComponent.h"
72 #include "AliHLTTPCCFComparisonComponent.h"
73 // #include "AliHLTTPCCalibSeedMakerComponent.h"
74 // #include "AliHLTTPCCalibTimeComponent.h"
75 // #include "AliHLTTPCCalibTimeGainComponent.h"
76 // #include "AliHLTTPCCalibrationComponent.h"
77 #include "AliHLTTPCDataCheckerComponent.h"
78 #include "AliHLTTPCHWCFEmulatorComponent.h"
79 #include "AliHLTTPCHWCFConsistencyControlComponent.h"
80 #include "AliHLTTPCDataCompressionComponent.h"
81 #include "AliHLTTPCDataCompressionMonitorComponent.h"
82
83 /** ROOT macro for the implementation of ROOT specific class methods */
84 ClassImp(AliHLTTPCAgent)
85
86 AliHLTTPCAgent::AliHLTTPCAgent()
87   : AliHLTModuleAgent("TPC")
88   , fRawDataHandler(NULL)
89   , fTracksegsDataHandler(NULL)
90   , fClustersDataHandler(NULL)
91   , fCompressionMonitorHandler(NULL)
92 {
93   // see header file for class documentation
94   // or
95   // refer to README to build package
96   // or
97   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
98 }
99
100 AliHLTTPCAgent::~AliHLTTPCAgent()
101 {
102   // see header file for class documentation
103 }
104
105 int AliHLTTPCAgent::CreateConfigurations(AliHLTConfigurationHandler* handler,
106                                          AliRawReader* rawReader,
107                                          AliRunLoader* runloader) const
108 {
109   // see header file for class documentation
110   if (handler) {
111
112     // This the tracking configuration for the full TPC
113     // - 216 clusterfinders (1 per partition)
114     // - 36 slice trackers
115     // - one global merger
116     // - the esd converter
117     // The ESD is shipped embedded into a TTree
118     int iMinSlice=0; 
119     int iMaxSlice=35;
120     int iMinPart=0;
121     int iMaxPart=5;
122     TString arg;
123     TString mergerInput;
124     TString sinkRawData;
125     TString sinkClusterInput;
126     TString sinkHWClusterInput;
127     TString dEdXInput;
128     TString compressorInput;
129     for (int slice=iMinSlice; slice<=iMaxSlice; slice++) {
130       TString trackerInput;
131       for (int part=iMinPart; part<=iMaxPart; part++) {
132         TString publisher, cf;
133
134         // digit publisher components
135         publisher.Form("TPC-DP_%02d_%d", slice, part);
136         if (rawReader || !runloader) {
137           // AliSimulation: use the AliRawReaderPublisher if the raw reader is available
138           // Alireconstruction: indicated by runloader==NULL, run always on raw data
139           int ddlno=768;
140           if (part>1) ddlno+=72+4*slice+(part-2);
141           else ddlno+=2*slice+part;
142           arg.Form("-minid %d -datatype 'DDL_RAW ' 'TPC '  -dataspec 0x%02x%02x%02x%02x -silent", ddlno, slice, slice, part, part);
143           handler->CreateConfiguration(publisher.Data(), "AliRawReaderPublisher", NULL , arg.Data());
144         } else {
145           arg.Form("-slice %d -partition %d", slice, part);
146           handler->CreateConfiguration(publisher.Data(), "TPCDigitPublisher", NULL , arg.Data());
147         }
148
149         if (sinkRawData.Length()>0) sinkRawData+=" ";
150         sinkRawData+=publisher;
151
152         // cluster finder components
153         cf.Form("TPC-CF_%02d_%d", slice, part);
154         arg="-release-memory -publish-raw";
155         if (!rawReader && runloader) {
156           arg+=" -do-mc";
157           handler->CreateConfiguration(cf.Data(), "TPCClusterFinderUnpacked", publisher.Data(), arg.Data());
158         } else {
159           handler->CreateConfiguration(cf.Data(), "TPCClusterFinder32Bit", publisher.Data(),arg.Data());
160         }
161
162         // Hardware CF emulator
163         // soon going to replace the software clusterfinder
164         TString hwcfemu;
165         hwcfemu.Form("TPC-HWCFEmu_%02d_%d", slice, part);
166         handler->CreateConfiguration(hwcfemu.Data(), "TPCHWClusterFinderEmulator", publisher.Data(), "-do-mc 1");
167         if (compressorInput.Length()>0) compressorInput+=" ";
168         compressorInput+=hwcfemu;
169
170         TString hwcf;
171         hwcf.Form("TPC-HWCF_%02d_%d", slice, part);
172         handler->CreateConfiguration(hwcf.Data(), "TPCHWClusterTransform",hwcfemu.Data(), "-publish-raw");
173
174         if (trackerInput.Length()>0) trackerInput+=" ";
175         trackerInput+=hwcf;
176         if (dEdXInput.Length()>0) dEdXInput+=" ";
177         dEdXInput+=hwcf;
178         if (sinkClusterInput.Length()>0) sinkClusterInput+=" ";
179         sinkClusterInput+=cf;
180         if (sinkHWClusterInput.Length()>0) sinkHWClusterInput+=" ";
181         sinkHWClusterInput+=hwcf;
182       }
183       TString tracker;
184       // tracker finder components
185       tracker.Form("TPC-TR_%02d", slice);
186       handler->CreateConfiguration(tracker.Data(), "TPCCATracker", trackerInput.Data(), "");
187
188       if (mergerInput.Length()>0) mergerInput+=" ";
189       mergerInput+=tracker;
190
191     }
192
193     // GlobalMerger component
194     handler->CreateConfiguration("TPC-globalmerger","TPCCAGlobalMerger",mergerInput.Data(),"");
195
196     // dEdx component
197     if (dEdXInput.Length()>0) dEdXInput+=" ";
198     dEdXInput+="TPC-globalmerger";
199
200     handler->CreateConfiguration("TPC-dEdx","TPCdEdx",dEdXInput.Data(),"");
201
202     // compression component
203     if (compressorInput.Length()>0) compressorInput+=" ";
204     compressorInput+="TPC-globalmerger";
205     handler->CreateConfiguration("TPC-compression", "TPCDataCompressor", compressorInput.Data(), "");
206     handler->CreateConfiguration("TPC-compression-huffman-trainer", "TPCDataCompressor", compressorInput.Data(),"-deflater-mode 3");
207     handler->CreateConfiguration("TPC-compression-monitoring-component", "TPCDataCompressorMonitor", "TPC-compression TPC-hwcfdata","-pushback-period=30");
208     handler->CreateConfiguration("TPC-compression-monitoring", "ROOTFileWriter", "TPC-compression-monitoring-component","-concatenate-events -overwrite -datafile HLT.TPCDataCompression-statistics.root");
209
210     // the esd converter configuration
211     TString converterInput="TPC-globalmerger";
212     if (!rawReader && runloader) {
213       // propagate cluster info to the esd converter in order to fill the MC information
214       handler->CreateConfiguration("TPC-clustermc-info", "BlockFilter"   , sinkHWClusterInput.Data(), "-datatype 'CLMCINFO' 'TPC '");  
215       handler->CreateConfiguration("TPC-mcTrackMarker","TPCTrackMCMarker","TPC-globalmerger TPC-clustermc-info","" );
216       converterInput+=" ";
217       converterInput+="TPC-mcTrackMarker";
218     }
219     handler->CreateConfiguration("TPC-esd-converter", "TPCEsdConverter"   , converterInput.Data(), "");
220
221     // cluster dump collection
222     handler->CreateConfiguration("TPC-clusters", "BlockFilter"   , sinkClusterInput.Data(), "-datatype 'CLUSTERS' 'TPC ' -datatype 'CLMCINFO' 'TPC '");
223     handler->CreateConfiguration("TPC-raw-clusters", "BlockFilter"   , sinkClusterInput.Data(), "-datatype 'CLUSTRAW' 'TPC ' -datatype 'CLMCINFO' 'TPC '");
224     handler->CreateConfiguration("TPC-hwclusters", "BlockFilter"   , sinkHWClusterInput.Data(), "-datatype 'CLUSTERS' 'TPC ' -datatype 'CLMCINFO' 'TPC '");
225     handler->CreateConfiguration("TPC-raw-hwclusters", "BlockFilter"   , sinkHWClusterInput.Data(), "-datatype 'CLUSTRAW' 'TPC ' -datatype 'CLMCINFO' 'TPC '");
226
227     // raw data
228     handler->CreateConfiguration("TPC-raw-data", "BlockFilter"   , sinkRawData.Data(), "");
229
230     handler->CreateConfiguration("TPC-hwcfdata", "BlockFilter"   , compressorInput.Data(), "-datatype 'HWCLUST1' 'TPC '");
231
232     /////////////////////////////////////////////////////////////////////////////////////
233     //
234     // dumps on the ALTRO digit level
235     //
236     // selected channel dump
237     arg.Form("-datafile selected-channel.dump -specfmt=_0x%%08x -subdir -blcknofmt= -idfmt=");
238     handler->CreateConfiguration("TPC-selected-altro-digits", "TPCDigitDump", "RCU-channelselect", arg.Data());
239
240     // raw channel dump
241     arg.Form("-datafile channel.dump -specfmt=_0x%%08x -subdir -blcknofmt= -idfmt=");
242     handler->CreateConfiguration("TPC-raw-altro-digits", "TPCDigitDump", "TPC-raw-data", arg.Data());
243
244     /////////////////////////////////////////////////////////////////////////////////////
245     //
246     // a kChain HLTOUT configuration for processing of {'TRAKSEGS':'TPC '} data blocks
247     // collects the data blocks, merges the tracks and produces an ESD object
248
249     // publisher component
250     handler->CreateConfiguration("TPC-hltout-tracksegs-publisher", "AliHLTOUTPublisher"   , NULL, "");
251
252     // GlobalMerger component
253     handler->CreateConfiguration("TPC-hltout-tracksegs-merger", "TPCGlobalMerger", "TPC-hltout-tracksegs-publisher", "");
254
255     // the esd converter configuration
256     handler->CreateConfiguration("TPC-hltout-tracksegs-esd-converter", "TPCEsdConverter", "TPC-hltout-tracksegs-merger", "");
257
258     /////////////////////////////////////////////////////////////////////////////////////
259     //
260     // a kChain HLTOUT configuration for processing of {'TRACKS  ':'TPC '} data blocks
261     // produces an ESD object from the track structure
262
263     // publisher component
264     handler->CreateConfiguration("TPC-hltout-tracks-publisher", "AliHLTOUTPublisher"   , NULL, "");
265
266     // the esd converter configuration
267     handler->CreateConfiguration("TPC-hltout-tracks-esd-converter", "TPCEsdConverter", "TPC-hltout-tracks-publisher", "");
268
269     /////////////////////////////////////////////////////////////////////////////////////
270     //
271     // a kChain HLTOUT configuration for processing of {'CLUSTERS':'TPC '} data blocks
272     // stores the blocks in file HLT.TPC.Clusters.root in HOMER format
273
274     // publisher component
275     handler->CreateConfiguration("TPC-hltout-cluster-publisher", "AliHLTOUTPublisher"   , NULL, "");
276
277     // the HLTOUT component collects the blocks and stores the file
278     handler->CreateConfiguration("TPC-hltout-cluster-dump", "HLTOUT", "TPC-hltout-cluster-publisher", "-digitfile HLT.TPC.Clusters.root -rawout=off -links 2");
279
280     /////////////////////////////////////////////////////////////////////////////////////
281     //
282     // monitoring of compressed TPC data {CLUSTRAW:TPC }, {REMCLSCM,TPC }, {CLSTRKCM,TPC }
283     // 
284
285     // publisher component
286     handler->CreateConfiguration("TPC-hltout-compressionmonitor-publisher", "AliHLTOUTPublisher"   , NULL,
287                                  "-datatype HWCLUST1 'TPC ' "
288                                  "-datatype CLUSTRAW 'TPC ' "
289                                  "-datatype REMCLSCM 'TPC ' "
290                                  "-datatype CLSTRKCM 'TPC ' "
291                                  "-datatype REMCLIDS 'TPC ' "
292                                  "-datatype CLIDSTRK 'TPC ' "
293                                  );
294
295     // the HLTOUT component collects the blocks and stores the file
296     handler->CreateConfiguration("TPC-hltout-compressionmonitor", "TPCDataCompressorMonitor", "TPC-hltout-compressionmonitor-publisher", "-histogram-file HLT.TPC-compression-statistics.root -publishing-mode off");
297   }
298
299   return 0;
300 }
301
302 const char* AliHLTTPCAgent::GetReconstructionChains(AliRawReader* /*rawReader*/,
303                                                     AliRunLoader* runloader) const
304 {
305   // see header file for class documentation
306   if (runloader) {
307     // reconstruction chains for AliRoot simulation
308     // Note: run loader is only available while running embedded into
309     // AliRoot simulation
310     //if (runloader->GetLoader("TPCLoader") != NULL)
311       //return "TPC-esd-converter TPC-clusters";
312
313     // 2010-10-26 TPC clusters not written to HLTOUT in order to make the simulation
314     // closer to the real data 
315     //return "TPC-clusters";
316   }
317   return NULL;
318 }
319
320 const char* AliHLTTPCAgent::GetRequiredComponentLibraries() const
321 {
322   // see header file for class documentation
323
324   // actually, the TPC library has dependencies to Util and RCU
325   // so the two has to be loaded anyhow before we get here
326   //return "libAliHLTUtil.so libAliHLTRCU.so";
327   return "libAliHLTUtil.so";
328 }
329
330 int AliHLTTPCAgent::RegisterComponents(AliHLTComponentHandler* pHandler) const
331 {
332   // see header file for class documentation
333   if (!pHandler) return -EINVAL;
334
335 //   pHandler->AddComponent(new AliHLTTPCCalibCEComponent);
336 //   pHandler->AddComponent(new AliHLTTPCCalibPulserComponent);
337 //   pHandler->AddComponent(new AliHLTTPCCalibPedestalComponent);
338   pHandler->AddComponent(new AliHLTTPCCompModelInflaterComponent);
339   pHandler->AddComponent(new AliHLTTPCCompModelDeflaterComponent);
340   pHandler->AddComponent(new AliHLTTPCCompModelDeconverterComponent);
341   pHandler->AddComponent(new AliHLTTPCCompModelConverterComponent);
342   pHandler->AddComponent(new AliHLTTPCCompDumpComponent);
343   pHandler->AddComponent(new AliHLTTPCCAInputDataCompressorComponent);
344   pHandler->AddComponent(new AliHLTTPCCATrackerComponent);
345   pHandler->AddComponent(new AliHLTTPCCATrackerOutputConverter);
346   pHandler->AddComponent(new AliHLTTPCCAGlobalMergerComponent);
347   pHandler->AddComponent(new AliHLTTPCTrackMCMarkerComponent);
348   pHandler->AddComponent(new AliHLTTPCGlobalMergerComponent);
349   pHandler->AddComponent(new AliHLTTPCdEdxComponent);
350   pHandler->AddComponent(new AliHLTTPCdEdxMonitoringComponent);
351   pHandler->AddComponent(new AliHLTTPCSliceTrackerComponent);
352   pHandler->AddComponent(new AliHLTTPCClusterFinderComponent(AliHLTTPCClusterFinderComponent::kClusterFinderPacked));
353   pHandler->AddComponent(new AliHLTTPCClusterFinderComponent(AliHLTTPCClusterFinderComponent::kClusterFinderUnpacked));
354   pHandler->AddComponent(new AliHLTTPCClusterFinderComponent(AliHLTTPCClusterFinderComponent::kClusterFinderDecoder));
355   pHandler->AddComponent(new AliHLTTPCClusterFinderComponent(AliHLTTPCClusterFinderComponent::kClusterFinder32Bit));
356   pHandler->AddComponent(new AliHLTTPCRawDataUnpackerComponent);
357   pHandler->AddComponent(new AliHLTTPCDigitPublisherComponent);
358   pHandler->AddComponent(new AliHLTTPCDigitDumpComponent);
359   pHandler->AddComponent(new AliHLTTPCClusterDumpComponent);
360   pHandler->AddComponent(new AliHLTTPCEsdWriterComponent::AliWriter);
361   pHandler->AddComponent(new AliHLTTPCEsdWriterComponent::AliConverter);
362   pHandler->AddComponent(new AliHLTTPCOfflineClustererComponent);
363   pHandler->AddComponent(new AliHLTTPCOfflineTrackerComponent);
364   pHandler->AddComponent(new AliHLTTPCOfflineTrackerCalibComponent);
365   pHandler->AddComponent(new AliHLTTPCOfflineCalibrationComponent);
366   pHandler->AddComponent(new AliHLTTPCClusterHistoComponent);
367   pHandler->AddComponent(new AliHLTTPCHistogramHandlerComponent);
368   //pHandler->AddComponent(new AliHLTTPCCalibTracksComponent);
369   pHandler->AddComponent(new AliHLTTPCTrackHistoComponent);
370   pHandler->AddComponent(new AliHLTTPCTrackDumpComponent);
371   pHandler->AddComponent(new AliHLTTPCHWCFDataReverterComponent);
372   pHandler->AddComponent(new AliHLTTPCHWClusterTransformComponent);
373   pHandler->AddComponent(new AliHLTTPCCFComparisonComponent);
374 //   pHandler->AddComponent(new AliHLTTPCCalibSeedMakerComponent);
375 //   pHandler->AddComponent(new AliHLTTPCCalibTimeComponent);
376 //   pHandler->AddComponent(new AliHLTTPCCalibTimeGainComponent);
377 //   pHandler->AddComponent(new AliHLTTPCCalibrationComponent);
378   pHandler->AddComponent(new AliHLTTPCDataCheckerComponent);
379   pHandler->AddComponent(new AliHLTTPCHWCFEmulatorComponent);
380 //  pHandler->AddComponent(new AliHLTTPCHWCFConsistencyControlComponent);  //FIXME: Causes crash: https://savannah.cern.ch/bugs/?83677
381   pHandler->AddComponent(new AliHLTTPCDataCompressionComponent);
382   pHandler->AddComponent(new AliHLTTPCDataCompressionMonitorComponent);
383   return 0;
384 }
385
386 int AliHLTTPCAgent::GetHandlerDescription(AliHLTComponentDataType dt,
387                                           AliHLTUInt32_t spec,
388                                           AliHLTOUTHandlerDesc& desc) const
389 {
390   // see header file for class documentation
391
392   // raw data blocks to be fed into offline reconstruction
393   if (dt==(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC)) {
394     int slice=AliHLTTPCDefinitions::GetMinSliceNr(spec);
395     int part=AliHLTTPCDefinitions::GetMinPatchNr(spec);
396     if (slice==AliHLTTPCDefinitions::GetMaxSliceNr(spec) &&
397         part==AliHLTTPCDefinitions::GetMaxPatchNr(spec)) {
398       desc=AliHLTOUTHandlerDesc(kRawReader, dt, GetModuleId());
399       return 1;
400     } else {
401       HLTWarning("handler can not process merged data from multiple ddls:"
402                  " min slice %d, max slice %d, min part %d, max part %d",
403                  slice, AliHLTTPCDefinitions::GetMaxSliceNr(spec),
404                  part, AliHLTTPCDefinitions::GetMaxPatchNr(spec));
405       return 0;
406     }
407   }
408
409   // dump for {'CLUSTERS':'TPC '} blocks stored in a 'digit' file
410   if (dt==AliHLTTPCDefinitions::fgkClustersDataType) {
411       desc=AliHLTOUTHandlerDesc(kChain, dt, GetModuleId());
412       return 1;
413   }
414
415   // define handlers for all blocks related to compression, flag if the
416   // cluster id blocks are existing, this will be used to decide
417   // whether to create the handler or not
418   // {'CLUSTRAW':'TPC '}
419   // {'HWCLUST1':'TPC '}
420   // {'REMCLSCM':'TPC '}
421   // {'CLSTRKCM':'TPC '}
422   // {'REMCLIDS':'TPC '}
423   // {'CLIDSTRK':'TPC '}
424   if (dt==AliHLTTPCDefinitions::RawClustersDataType() ||
425       dt==AliHLTTPCDefinitions::HWClustersDataType() ||
426       dt==AliHLTTPCDefinitions::RemainingClustersCompressedDataType() ||
427       dt==AliHLTTPCDefinitions::ClusterTracksCompressedDataType()) {
428       desc=AliHLTOUTHandlerDesc(kProprietary, dt, GetModuleId());
429       return 1;
430   }
431   if (dt==AliHLTTPCDefinitions::RemainingClusterIdsDataType() ||
432       dt==AliHLTTPCDefinitions::ClusterIdTracksDataType()) {
433       desc=AliHLTOUTHandlerDesc(kProprietary, dt, GetModuleId());
434       const_cast<AliHLTTPCAgent*>(this)->SetBit(kHaveCompressedClusterIdDataBlock);
435       return 1;
436   }
437
438   // {'CLMCINFO':'TPC '} 
439   if (dt==AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo) {
440       desc=AliHLTOUTHandlerDesc(kProprietary, dt, GetModuleId());
441       return 1;
442   }
443
444   // afterburner for {'TRAKSEGS':'TPC '} blocks to be converted to ESD format
445   if (dt==AliHLTTPCDefinitions::fgkTrackSegmentsDataType) {
446       desc=AliHLTOUTHandlerDesc(kChain, dt, GetModuleId());
447       return 1;
448   }
449
450   // afterburner for {'TRACKS  ':'TPC '} block to be converted to ESD format
451   // there is only one data block
452   if (dt==AliHLTTPCDefinitions::fgkTracksDataType) {
453       desc=AliHLTOUTHandlerDesc(kChain, dt, GetModuleId());
454       return 1;
455   }
456   return 0;
457 }
458
459 AliHLTOUTHandler* AliHLTTPCAgent::GetOutputHandler(AliHLTComponentDataType dt,
460                                                    AliHLTUInt32_t /*spec*/)
461 {
462   // see header file for class documentation
463
464   // raw data blocks to be fed into offline reconstruction
465   if (dt==(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC)) {
466     if (!fRawDataHandler) {
467       fRawDataHandler=new AliHLTTPCAgent::AliHLTTPCRawDataHandler;
468     }
469     return fRawDataHandler;
470   }
471
472   // dump for {'CLUSTERS':'TPC '}, stored in a file HLT.TPC.Clusters.root in HOMER format
473   if (dt==AliHLTTPCDefinitions::fgkClustersDataType) {
474     if (fClustersDataHandler==NULL)
475       fClustersDataHandler=new AliHLTOUTHandlerChain("chains=TPC-hltout-cluster-dump libHLTsim.so libAliHLTUtil.so");
476     return fClustersDataHandler;
477   }
478
479   // afterburner for {'TRAKSEGS':'TPC '} blocks to be converted to ESD format
480   // in a kChain HLTOUT handler
481   if (dt==AliHLTTPCDefinitions::fgkTrackSegmentsDataType) {
482     if (fTracksegsDataHandler==NULL)
483       fTracksegsDataHandler=new AliHLTOUTHandlerChain("chains=TPC-hltout-tracksegs-esd-converter");
484     return fTracksegsDataHandler;
485   }
486
487   // afterburner for {'TRACKS  ':'TPC '} block to be converted to ESD format
488   // there is only one data block
489   if (dt==AliHLTTPCDefinitions::fgkTracksDataType) {
490     return new AliHLTOUTHandlerChain("chains=TPC-hltout-tracks-esd-converter");
491   }
492
493   // monitoring of compressed data if cluster verification blocks exist
494   // {'REMCLIDS':'TPC '}
495   // {'CLIDSTRK':'TPC '}
496   // FIXME: needs to be commissioned
497   // if (dt==AliHLTTPCDefinitions::RawClustersDataType() ||
498   //     dt==AliHLTTPCDefinitions::HWClustersDataType() ||
499   //     dt==AliHLTTPCDefinitions::RemainingClustersCompressedDataType() ||
500   //     dt==AliHLTTPCDefinitions::ClusterTracksCompressedDataType() ||
501   //     dt==AliHLTTPCDefinitions::RemainingClusterIdsDataType() ||
502   //     dt==AliHLTTPCDefinitions::ClusterIdTracksDataType()) {
503   //   const char* arg="chains=TPC-hltout-compressionmonitor";
504   //   if (!TestBit(kHaveCompressedClusterIdDataBlock))
505   //     arg="chains=TPC-hltout-compressionmonitorpublisher";
506   //   if (!fCompressionMonitorHandler)
507   //     fCompressionMonitorHandler=new AliHLTOUTHandlerChain(arg);
508   //   return fCompressionMonitorHandler;
509   // }
510
511   return NULL;
512 }
513
514 int AliHLTTPCAgent::DeleteOutputHandler(AliHLTOUTHandler* pInstance)
515 {
516   // see header file for class documentation
517   if (pInstance==NULL) return -EINVAL;
518
519   if (pInstance==fRawDataHandler) {
520     delete fRawDataHandler;
521     fRawDataHandler=NULL;
522   }
523
524   if (pInstance==fTracksegsDataHandler) {
525     delete fTracksegsDataHandler;
526     fTracksegsDataHandler=NULL;
527   }
528
529   if (pInstance==fClustersDataHandler) {
530     delete fClustersDataHandler;
531     fClustersDataHandler=NULL;
532   }
533
534   if (pInstance==fCompressionMonitorHandler) {
535     delete fCompressionMonitorHandler;
536     fCompressionMonitorHandler=NULL;
537   }
538
539   return 0;
540 }
541
542 AliHLTTPCAgent::AliHLTTPCRawDataHandler::AliHLTTPCRawDataHandler()
543 {
544   // see header file for class documentation
545 }
546
547 AliHLTTPCAgent::AliHLTTPCRawDataHandler::~AliHLTTPCRawDataHandler()
548 {
549   // see header file for class documentation
550 }
551
552 int AliHLTTPCAgent::AliHLTTPCRawDataHandler::ProcessData(AliHLTOUT* pData)
553 {
554   // see header file for class documentation
555   if (!pData) return -EINVAL;
556   AliHLTComponentDataType dt=kAliHLTVoidDataType;
557   AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
558   int iResult=pData->GetDataBlockDescription(dt, spec);
559   if (iResult>=0) {
560     int slice=AliHLTTPCDefinitions::GetMinSliceNr(spec);
561     int part=AliHLTTPCDefinitions::GetMinPatchNr(spec);
562     if (slice==AliHLTTPCDefinitions::GetMaxSliceNr(spec) &&
563         part==AliHLTTPCDefinitions::GetMaxPatchNr(spec)) {
564       iResult=768;
565       if (part>1) iResult+=72+4*slice+(part-2);
566       else iResult+=2*slice+part;
567     } else {
568       HLTError("handler can not process merged data from multiple ddls:"
569                " min slice %d, max slice %d, min part %d, max part %d",
570                slice, AliHLTTPCDefinitions::GetMaxSliceNr(spec),
571                part, AliHLTTPCDefinitions::GetMaxPatchNr(spec));
572       iResult=-EBADMSG;
573     }
574   }
575   return iResult;
576 }