implementing selection by sector for cluster conversion, handling of MC data block...
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 15 Jun 2011 10:02:09 +0000 (10:02 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 15 Jun 2011 10:02:09 +0000 (10:02 +0000)
HLT/TPCLib/AliHLTTPCClusterAccessHLTOUT.cxx
HLT/TPCLib/AliHLTTPCClusterAccessHLTOUT.h

index e3c3de6..fcfb8ae 100644 (file)
 #include "AliHLTTPCDefinitions.h"
 #include "AliHLTTPCClusterDataFormat.h"
 #include "AliHLTOUT.h"
+#include "AliHLTComponent.h"
 #include "AliLog.h"
 #include "AliHLTSystem.h"
 #include "AliHLTPluginBase.h"
 #include "AliTPCclusterMI.h"
 #include "TClonesArray.h"
+#include <cstdlib>
+#include <string>
+#include <memory>
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTTPCClusterAccessHLTOUT)
 
 AliHLTTPCClusterAccessHLTOUT::AliHLTTPCClusterAccessHLTOUT()
   : TObject()
+  , fVerbosity(0)
   , fClusters(NULL)
 {
   // see header file for class documentation
@@ -56,11 +61,27 @@ AliHLTTPCClusterAccessHLTOUT::~AliHLTTPCClusterAccessHLTOUT()
   }
 }
 
-void AliHLTTPCClusterAccessHLTOUT::Execute(const char *method,  const char */*params*/, Int_t *error)
+void AliHLTTPCClusterAccessHLTOUT::Execute(const char *method,  const char *params, Int_t *error)
 {
   /// inherited from TObject: abstract command interface
   if (strcmp(method, "read")==0) {
-    int iResult=ProcessClusters();
+    int iResult=ProcessClusters(params);
+    if (error) *error=iResult;
+    return;
+  }
+  if (strcmp(method, "verbosity")==0) {
+    int iResult=0;
+    if (params) {
+      char* dummy;
+      int value=strtol(params, &dummy, 0);
+      if (dummy==NULL) {
+       fVerbosity=value;
+      } else {
+       AliError("invalid argument for command 'verbosity', expecting string with number");
+      }
+    } else {
+      iResult=-EINVAL;
+    }
     if (error) *error=iResult;
     return;
   }
@@ -97,12 +118,35 @@ void AliHLTTPCClusterAccessHLTOUT::Print(Option_t */*option*/) const
   }
 }
 
-int AliHLTTPCClusterAccessHLTOUT::ProcessClusters()
+int AliHLTTPCClusterAccessHLTOUT::ProcessClusters(const char* params)
 {
   /// process the cluster data from HLTOUT and fill array
   /// the cluster data can be in many different formats, e.g.
   /// raw or compressed
   int iResult=0;
+  TString strparams(params);
+  int minSlice=0, maxSlice=35, minPart=0, maxPart=5;
+  std::auto_ptr<TObjArray> tokens(strparams.Tokenize(" "));
+  if (!tokens.get()) return -ENOMEM;
+  for (int i=0; i< tokens->GetEntriesFast(); i++) {
+    if (!tokens->At(i)) continue;
+    TString argument=tokens->At(i)->GetName();
+    if (argument.BeginsWith("sector=")) {
+      argument.ReplaceAll("sector=", "");
+      int sector=argument.Atoi();
+      // the offline code enumerates first the 36 inner (partitions 0+1) and then 36 outer
+      // sectors (partitions 2-5)
+      if (fVerbosity>0) AliInfo(Form("processing HLT clusters for sector %d", sector));
+      if (sector<36) { // inner sectors
+       minSlice=maxSlice=sector;
+       minPart=0; maxPart=1;
+      } else { // outer sectors
+       minSlice=maxSlice=sector-36;
+       minPart=2; maxPart=5;
+      }
+    }
+  }
+
   if (!fClusters) {
     fClusters=new TClonesArray("AliTPCclusterMI");
   }
@@ -119,15 +163,77 @@ int AliHLTTPCClusterAccessHLTOUT::ProcessClusters()
     return -ENODEV;
   }
 
-  if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkClustersDataType)>=0) {
-    iResult=ReadAliHLTTPCClusterData(pHLTOUT, fClusters);
+  for (int slice=minSlice; slice<=maxSlice; slice++) {
+    for (int part=minPart; part<=maxPart; part++) {
+      if (fVerbosity>0) AliInfo(Form("processing HLT clusters for slice %d partitions %d", slice, part));
+      AliHLTUInt32_t spec=slice<<24 | slice<<16 | part<<8 | part;
+      AliHLTTPCClusterMCDataList tpcClusterLabels;
+      if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo, spec)>=0) {
+       iResult=ReadAliHLTTPCClusterMCData(pHLTOUT, tpcClusterLabels);
+      }
+
+      if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkClustersDataType, spec)>=0) {
+       iResult=ReadAliHLTTPCClusterData(pHLTOUT, fClusters);
+      }
+    }
   }
 
   pSystem->ReleaseHLTOUT(pHLTOUT);
   return iResult;
 }
 
-int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters) const
+int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterMCData(AliHLTOUT* pHLTOUT, AliHLTTPCClusterMCDataList &tpcClusterLabels) const
+{
+  // read cluster data from AliHLTTPCClusterData
+  int iResult=0;
+  if (!pHLTOUT) return -EINVAL;
+  do {
+    const AliHLTUInt8_t* pBuffer=NULL;
+    AliHLTUInt32_t size=0;
+    if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
+      continue;
+    }
+    if (pBuffer==NULL || size<4) {
+      AliError("invalid cluster mc data block");
+      continue;
+    }
+    const AliHLTTPCClusterMCData* clusterMCData = reinterpret_cast<const AliHLTTPCClusterMCData*>(pBuffer);
+    Int_t nLabels = (Int_t) clusterMCData->fCount;
+    if (nLabels*sizeof(AliHLTTPCClusterMCLabel) + sizeof(AliHLTTPCClusterMCData) != size) {
+      AliError("inconsistent cluster mc data block size, skipping block");
+      continue;
+    }
+    // id of the cluster is 
+    AliHLTComponentDataType dt=kAliHLTVoidDataType;
+    AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
+    if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
+      AliError("failed to retrieve data block description, skipping mc cluster data block ...");
+      continue;
+    }
+    AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
+    AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
+    if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr(specification) ||
+       partition!=AliHLTTPCDefinitions::GetMaxPatchNr(specification)) {
+      AliError(Form("can not read cluster mc data block with data of multiple partitions, skipping block %s %08x",
+                   AliHLTComponent::DataType2Text(dt).c_str(), specification));
+      continue;
+    }
+    const AliHLTTPCClusterMCLabel *labels = clusterMCData->fLabels;
+    for (int i=0; i<nLabels; i++) {
+      AliHLTUInt32_t id=AliHLTTPCSpacePointData::GetID(slice, partition, i);
+      if (tpcClusterLabels.find(id)==tpcClusterLabels.end()) {
+       // new cluster
+       tpcClusterLabels[id]=labels[i];
+      } else {
+       AliError(Form("cluster with ID 0x%08x already existing, skipping cluster %d of data block 0x%08x",
+                     id, i, specification));
+      }
+    }
+  } while (pHLTOUT->SelectNextDataBlock()>=0);
+  return iResult;
+}
+
+int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels) const
 {
   // read cluster data from AliHLTTPCClusterData
   int iResult=0;
@@ -142,6 +248,12 @@ int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, T
       AliError("invalid cluster data block");
       continue;
     }
+    AliHLTComponentDataType dt=kAliHLTVoidDataType;
+    AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
+    if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
+      AliError("failed to retrieve data block description, skipping mc cluster data block ...");
+      continue;
+    }
     const AliHLTTPCClusterData* clusterData = reinterpret_cast<const AliHLTTPCClusterData*>(pBuffer);
     Int_t nSpacepoints = (Int_t) clusterData->fSpacePointCnt;
     if (nSpacepoints*sizeof(AliHLTTPCSpacePointData) + sizeof(AliHLTTPCClusterData) != size) {
@@ -149,22 +261,36 @@ int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, T
       continue;
     }
     const AliHLTTPCSpacePointData *clusters = clusterData->fSpacePoints;
-    int offset=fClusters->GetEntries();
-    fClusters->ExpandCreate(offset+nSpacepoints);
+    int offset=pClusters->GetEntries();
+    pClusters->ExpandCreate(offset+nSpacepoints);
     for (int i=0; i<nSpacepoints; i++) {
-      if (!fClusters->At(offset+i)) continue;
-      AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(fClusters->At(offset+i));
+      if (!pClusters->At(offset+i)) continue;
+      AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
       if (!pCluster) {
        AliError("invalid object type, expecting AliTPCclusterMI");
        break; // this is a problem of all objects
       }
       pCluster->SetRow(clusters[i].fPadRow);
       pCluster->SetTimeBin(clusters[i].fZ);
-      pCluster->SetPad(clusters[i].fX);
+      pCluster->SetPad(clusters[i].fY);
+      pCluster->SetSigmaY2(clusters[i].fSigmaY2);
+      pCluster->SetSigmaZ2(clusters[i].fSigmaZ2);
       pCluster->SetQ(clusters[i].fCharge);
       pCluster->SetMax(clusters[i].fQMax);
+      if (tpcClusterLabels) {
+       if (tpcClusterLabels->find(clusters[i].fID)!=tpcClusterLabels->end()) {
+         const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusters[i].fID)->second.fClusterID;
+         for (int k=0; k<3; k++) {
+           // TODO: sort the labels according to the weight in order to assign the most likely mc label
+           // to the first component 
+           pCluster->SetLabel(mcWeights[k].fMCID, k);
+         }
+       } else {
+         AliError(Form("can not find mc label of cluster with id %0x08x", clusters[i].fID));
+       }
+      }
     }
-    AliInfo(Form("converted %d cluster(s)", nSpacepoints));
+    if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block 0x%08x", nSpacepoints, specification));
   } while (pHLTOUT->SelectNextDataBlock()>=0);
   return iResult;
 }
index 77d0381..06c45a7 100644 (file)
 ///
 
 #include "TObject.h"
+#include "AliHLTDataTypes.h"
+#include "AliHLTTPCClusterMCData.h"
+#include <map>
 
 class AliTPCClustersRow;
 class AliHLTOUT;
 class TClonesArray;
 
+typedef std::map<AliHLTUInt32_t, AliHLTTPCClusterMCLabel> AliHLTTPCClusterMCDataList;
+
 /**
  * @class AliHLTTPCClusterAccessHLTOUT
  * Generator for TPC cluster array from HLT TPC clusters in the HLTOUT
- * data stream.
+ * data stream. It uses the TObject method interface. Combined with dynamic
+ * loading, any cross dependency between the TPC code and HLT libraries
+ * can be avoided.
  *
+ * Creating the instance: 
+ * The class is implemented in libAliHLTTPC.so and can be loaded
+ * through the TClass interface (you might want to add
+ * further error messages on the various error conditions).
+ * <pre>
+ *     TObject* pClusterAccess=NULL;
+ *     TClass* pCl=NULL;
+ *     ROOT::NewFunc_t pNewFunc=NULL;
+ *     do {
+ *       pCl=TClass::GetClass("AliHLTTPCClusterAccessHLTOUT");
+ *     } while (!pCl && gSystem->Load("libAliHLTTPC.so")==0);
+ *     if (pCl && (pNewFunc=pCl->GetNew())!=NULL) {
+ *       void* p=(*pNewFunc)(NULL);
+ *       if (p) {
+ *         pClusterAccess=reinterpret_cast<TObject*>(p);
+ *       }
+ *     }
+ * </pre>
+ * 
+ * Usage:
+ * TObject::Execute can be used to execute commands. Command 'read'
+ * will get hold on the HLTOUT data and read the clusters. The const char*
+ * parameter 'param' is used to select the region.
+ * - param=NULL: read all
+ * - param="sector=sectorno"
+ * 'sectorno' specifies sector number in the offline code, range 0 and 71,
+ * enumerating first the 36 inner (partitions 0+1)  and then 36 outer sectors
+ * (partitions 2-5).
+ * 
+ * Command 'verbosity=level' sets the verbositylevel which is default 0
+ * (no info output).
+ * <pre>
+ *     pClusterAccess->Clear();
+ *     pClusterAccess->Execute("read", param);
+ *     TObject* pClusterAccess->FindObject("clusterarray");
+ * </pre>
+ * 
  * @ingroup alihlt_tpc
  */
 class AliHLTTPCClusterAccessHLTOUT : public TObject
@@ -46,10 +90,13 @@ class AliHLTTPCClusterAccessHLTOUT : public TObject
   virtual void        Print(Option_t *option="") const;
 
   /// process the cluster data block of various formats from HLTOUT
-  int ProcessClusters();
+  int ProcessClusters(const char* params);
+
+  /// process the cluster mc data block {CLMCINFO:TPC } from HLTOUT
+  int ReadAliHLTTPCClusterMCData(AliHLTOUT* pHLTOUT, AliHLTTPCClusterMCDataList &tpcClusterLabels) const;
 
   /// process the cluster data block {CLUSTERS:TPC } from HLTOUT
-  int ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters) const;
+  int ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels=NULL) const;
 
  private:
   /// copy constructor prohibited
@@ -57,7 +104,8 @@ class AliHLTTPCClusterAccessHLTOUT : public TObject
   /// assignment operator prohibited
   AliHLTTPCClusterAccessHLTOUT& operator=(const AliHLTTPCClusterAccessHLTOUT&);
 
-  TClonesArray* fClusters;
+  int fVerbosity; //! verbosity level
+  TClonesArray* fClusters; //! cluster array
 
   ClassDef(AliHLTTPCClusterAccessHLTOUT, 0)
 };