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