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