@brief
*/
-#if __GNUC__>= 3
-using namespace std;
-#endif
#include "AliHLTTPCHWClusterTransformComponent.h"
#include "AliHLTTPCDefinitions.h"
#include "AliHLTTPCTransform.h"
#include "AliHLTTPCSpacePointData.h"
#include "AliHLTTPCClusterDataFormat.h"
-#include "AliRawDataHeader.h"
+#include "AliHLTCDHWrapper.h"
+#include "AliHLTTPCRawCluster.h"
+#include "AliHLTTPCHWCFEmulator.h"
+#include "AliHLTTPCHWCFData.h"
+#include "AliHLTErrorGuard.h"
+#include "AliTPCTransform.h"
#include "AliCDBManager.h"
#include "AliCDBEntry.h"
#include <cerrno>
#include <sys/time.h>
+using namespace std;
+
ClassImp(AliHLTTPCHWClusterTransformComponent) //ROOT macro for the implementation of ROOT specific class methods
const char* AliHLTTPCHWClusterTransformComponent::fgkOCDBEntryHWTransform="HLT/ConfigTPC/TPCHWClusterTransform";
+AliHLTTPCClusterTransformation AliHLTTPCHWClusterTransformComponent::fgTransform;
+Bool_t AliHLTTPCHWClusterTransformComponent::fgTimeInitialisedFromEvent = 0;
+
AliHLTTPCHWClusterTransformComponent::AliHLTTPCHWClusterTransformComponent()
:
fDataId(kFALSE),
-fChargeThreshold(10),
-fTransform(),
+fPublishRawClusters(kFALSE),
+fpDecoder(NULL),
fBenchmark("HWClusterTransform")
{
// see header file for class documentation
fBenchmark.SetTimer(0,"total");
}
-AliHLTTPCHWClusterTransformComponent::~AliHLTTPCHWClusterTransformComponent() {
-// see header file for class documentation
+AliHLTTPCHWClusterTransformComponent::~AliHLTTPCHWClusterTransformComponent()
+{
+ // destructor
+ if (!fpDecoder) delete fpDecoder;
+ fpDecoder=NULL;
}
const char* AliHLTTPCHWClusterTransformComponent::GetComponentID() {
tgtList.clear();
tgtList.push_back(AliHLTTPCDefinitions::fgkClustersDataType| kAliHLTDataOriginTPC);
tgtList.push_back(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC );
+ tgtList.push_back(AliHLTTPCDefinitions::fgkRawClustersDataType | kAliHLTDataOriginTPC );
return tgtList.size();
}
return new AliHLTTPCHWClusterTransformComponent();
}
-int AliHLTTPCHWClusterTransformComponent::DoInit( int argc, const char** argv ) {
-// see header file for class documentation
+int AliHLTTPCHWClusterTransformComponent::DoInit( int argc, const char** argv )
+{
+ // see header file for class documentation
AliTPCcalibDB *calib=AliTPCcalibDB::Instance();
if(!calib){
}
calib->SetRun(GetRunNo());
calib->UpdateRunInformations(GetRunNo());
-
- int err = fTransform.Init( GetBz(), GetTimeStamp() );
-
- if( err!=0 ){
- HLTError("Cannot retrieve offline transform from AliTPCcalibDB");
- return -ENOENT;
+
+ if( !fgTransform.IsInitialised() ){
+ int err = fgTransform.Init( GetBz(), GetTimeStamp() );
+ if( err!=0 ){
+ HLTError(Form("Cannot retrieve offline transform from AliTPCcalibDB, AliHLTTPCClusterTransformation returns %d",err));
+ return -ENOENT;
+ }
}
int iResult=0;
if (iResult>=0 && argc>0)
iResult=ConfigureFromArgumentString(argc, argv);
+ if (iResult>=0) {
+ fpDecoder=new AliHLTTPCHWCFData;
+ if (!fpDecoder) iResult=-ENOMEM;
+ }
+
return iResult;
} // end DoInit()
int AliHLTTPCHWClusterTransformComponent::DoDeinit() {
// see header file for class documentation
+ if (!fpDecoder) delete fpDecoder;
+ fpDecoder=NULL;
+ fgTransform.DeInit();
return 0;
}
AliHLTUInt32_t& size,
vector<AliHLTComponentBlockData>& outputBlocks ){
// see header file for class documentation
-
+
UInt_t maxOutSize = size;
size = 0;
int iResult = 0;
- if(GetFirstInputBlock( kAliHLTDataTypeSOR ) || GetFirstInputBlock( kAliHLTDataTypeEOR )){
- return 0;
+ if(!IsDataEvent()) return 0;
+
+ if (!fpDecoder) return -ENODEV;
+ if( !fgTransform.IsInitialised() ){
+ HLTError(" TPC Transformation is not initialised ");
+ return -ENOENT;
}
fBenchmark.StartNewEvent();
fBenchmark.Start(0);
- fTransform.SetCurrentTimeStamp( GetTimeStamp() );
-
- for( unsigned long ndx=0; ndx<evtData.fBlockCnt; ndx++ ){
+ // Initialise the transformation here once more for the case of off-line reprocessing
+ if( !fgTimeInitialisedFromEvent ){
+ Long_t currentTime = static_cast<AliHLTUInt32_t>(time(NULL));
+ Long_t eventTimeStamp = GetTimeStamp();
+ if( TMath::Abs( fgTransform.GetCurrentTimeStamp() - eventTimeStamp )>60 &&
+ TMath::Abs( currentTime - eventTimeStamp)>60*60*5 ){
+ int err = fgTransform.SetCurrentTimeStamp( eventTimeStamp );
+ if( err!=0 ){
+ HLTError(Form("Cannot set time stamp, AliHLTTPCClusterTransformation returns %d",err));
+ return -ENOENT;
+ }
+ }
+ fgTimeInitialisedFromEvent = 1;
+ }
+
+ for( unsigned long ndx=0; ndx<evtData.fBlockCnt; ndx++ ){
const AliHLTComponentBlockData *iter = blocks+ndx;
UInt_t minPartition = AliHLTTPCDefinitions::GetMinPatchNr(*iter);
//UInt_t maxSlice = AliHLTTPCDefinitions::GetMaxSliceNr(*iter);
//UInt_t maxPartition = AliHLTTPCDefinitions::GetMaxPatchNr(*iter);
+ float padpitch=1.0;
+ if ((int)minPartition<AliHLTTPCTransform::GetNRowLow())
+ padpitch=AliHLTTPCTransform::GetPadPitchWidthLow();
+ else
+ padpitch=AliHLTTPCTransform::GetPadPitchWidthUp();
+ float zwidth=AliHLTTPCTransform::GetZWidth();
fBenchmark.SetName(Form("HWClusterTransform slice %d patch %d",minSlice,minPartition));
HLTDebug("minSlice: %d, minPartition: %d", minSlice, minPartition);
AliHLTTPCClusterData* outPtr = (AliHLTTPCClusterData*)outputPtr;
+ outPtr->fSpacePointCnt=0;
long maxPoints = ((long)maxOutSize-size-sizeof(AliHLTTPCClusterData))/sizeof(AliHLTTPCSpacePointData);
-
-
+
AliHLTUInt32_t *buffer;
- buffer = (AliHLTUInt32_t*)iter->fPtr;
-
- /*
- //cluster fabrication
- buffer = new AliHLTUInt32_t[14];
- //header
- buffer[0]=0xffffffff;
- buffer[1]=0xffffffff;
- buffer[2]=0xffffffff;
- buffer[3]=0xffffffff;
- buffer[4]=0xffffffff;
- buffer[5]=0xffffffff;
- buffer[6]=0xffffffff;
- buffer[7]=0xffffffff;
- //cluster 1
- buffer[8]=0xC60002EF;
- buffer[9]=0x0;
- buffer[10]=0x0;
- buffer[11]=0x0;
- buffer[12]=0x0;
- //RCU trailer
- buffer[13]=0x80000000;
- */
-
- // PrintDebug(buffer, 14);
+ buffer = (AliHLTUInt32_t*)iter->fPtr;
+ AliHLTCDHWrapper cdh(iter->fPtr);
// skip the first 8 32-bit CDH words
- buffer += 8;
- UInt_t bufferSize32 = ((Int_t)iter->fSize - sizeof(AliRawDataHeader) )/sizeof(AliHLTUInt32_t);
-
- //PrintDebug(buffer, (Int_t)iter->fSize/sizeof(AliHLTUInt32_t));
-
- long nAddedClusters = 0;
-
- for(UInt_t nWords=0; nWords<bufferSize32; nWords+=5){
- // for(UInt_t nWords=0; nWords<5; nWords+=5){
+ buffer += cdh.GetHeaderSize()/sizeof(AliHLTUInt32_t);
+ UInt_t bufferSize32 = ((Int_t)iter->fSize - cdh.GetHeaderSize() )/sizeof(AliHLTUInt32_t);
- // check if bit 31 and 30 of the 32-bit word is 11 -> cluster (10 is RCU trailer)
- AliHLTUInt32_t bit3130 = (buffer[nWords]>>30); // shift 30 to the right
-
- if(bit3130 == 0x3){ //beginning of a cluster
-
- //PrintDebug(&buffer[nWords], 5);
-
- if(nAddedClusters>=maxPoints){
+ if (fpDecoder->Init(reinterpret_cast<AliHLTUInt8_t*>(buffer), bufferSize32*sizeof(AliHLTUInt32_t))>=0 && fpDecoder->CheckVersion()>=0) {
+ for (AliHLTTPCHWCFData::iterator cl=fpDecoder->begin(); cl!=fpDecoder->end(); ++cl) {
+ if(outPtr->fSpacePointCnt>=maxPoints){
HLTWarning("No more space to add clusters, exiting!");
iResult = -ENOSPC;
break;
}
-
- AliHLTTPCSpacePointData cluster;
-
- //get the first word
- AliHLTUInt32_t rowCharge = buffer[nWords];
- AliHLTUInt8_t *rowPtr = reinterpret_cast<AliHLTUInt8_t*>(&rowCharge);
- rowPtr+=3; // this is to run for little endian architecture, the word is read from right to left
-
- cluster.fPadRow = (UChar_t)((*rowPtr)&0x3f);
- cluster.fCharge = ((UInt_t)rowCharge&0xFFFFFF)>>6; //24-bit mask to get out the charge and division with 64(>>6) for the gain correction
-
- Float_t tmpPad = *((Float_t*)&buffer[nWords+1]);
- Float_t tmpTime = *((Float_t*)&buffer[nWords+2]);
- cluster.fSigmaY2 = *((Float_t*)&buffer[nWords+3]);
- cluster.fSigmaZ2 = *((Float_t*)&buffer[nWords+4]);
-
-
- if(cluster.fCharge<fChargeThreshold) continue;
-
- // correct expressions for the error calculation
- // Kenneth: 12.11.2009 I'm not sure if this is a correct calculation. Leave it out for now since it is anyway not used later since it caused segfaults.
- // cluster.fSigmaY2 = TMath::Sqrt( *((Float_t*)&buffer[nWords+3]) - *((Float_t*)&buffer[nWords+1])* (*((Float_t*)&buffer[nWords+1])) );
- // cluster.fSigmaZ2 = TMath::Sqrt( *((Float_t*)&buffer[nWords+3]) - *((Float_t*)&buffer[nWords+1])* (*((Float_t*)&buffer[nWords+1])) );
-
- HLTDebug("padrow: %d, charge: %d, pad: %f, time: %f, errY: %f, errZ: %f \n", cluster.fPadRow, (UInt_t)cluster.fCharge, tmpPad, tmpTime, cluster.fSigmaY2, cluster.fSigmaZ2);
-
- cluster.fPadRow += AliHLTTPCTransform::GetFirstRow(minPartition);
-
+
+ AliHLTTPCSpacePointData& c=outPtr->fSpacePoints[outPtr->fSpacePointCnt];
+ int padrow=cl.GetPadRow();
+ if (padrow<0) {
+ // something wrong here, padrow is stored in the cluster header
+ // word which has bit pattern 0x3 in bits bit 30 and 31 which was
+ // not recognized
+ ALIHLTERRORGUARD(1, "can not read cluster header word");
+ break;
+ }
+ padrow+=AliHLTTPCTransform::GetFirstRow(minPartition);
+ AliHLTUInt32_t charge=cl.GetCharge();
+
+ float pad=cl.GetPad();
+ float time=cl.GetTime();
+ float sigmaY2=cl.GetSigmaY2();
+ float sigmaZ2=cl.GetSigmaZ2();
+ sigmaY2*=padpitch*padpitch;
+ sigmaZ2*=zwidth*zwidth;
+ c.SetPadRow(padrow);
+ c.SetCharge(charge);
+ c.SetSigmaY2(sigmaY2);
+ c.SetSigmaZ2(sigmaZ2);
+ c.SetQMax(cl.GetQMax());
+
Float_t xyz[3];
- fTransform.Transform( minSlice, cluster.fPadRow, tmpPad, tmpTime, xyz );
- cluster.fX = xyz[0];
- cluster.fY = xyz[1];
- cluster.fZ = xyz[2];
-
+ int err = fgTransform.Transform( minSlice, padrow, pad, time, xyz );
+ if( err!=0 ){
+ HLTWarning(Form("Cannot transform the cluster, AliHLTTPCClusterTransformation returns error %d, %s",err, fgTransform.GetLastError()));
+ continue;
+ }
+ c.SetX(xyz[0]);
+ c.SetY(xyz[1]);
+ c.SetZ(xyz[2]);
+
// set the cluster ID so that the cluster dump printout is the same for FCF and SCF
- cluster.SetID( minSlice, minPartition, nAddedClusters );
+ c.SetID( minSlice, minPartition, outPtr->fSpacePointCnt );
- HLTDebug("Cluster number %d: %f, Y: %f, Z: %f, charge: %d \n", nAddedClusters, cluster.fX, cluster.fY, cluster.fZ, (UInt_t)cluster.fCharge);
- outPtr->fSpacePoints[nAddedClusters] = cluster;
+ HLTDebug("Cluster number %d: %f, Y: %f, Z: %f, charge: %d \n", outPtr->fSpacePointCnt, cluster.fX, cluster.fY, cluster.fZ, (UInt_t)cluster.fCharge);
- nAddedClusters++;
- } // end of clusters starting with 11=0x3
- else if(bit3130 == 0x2){ // we have reached the beginning of the RCU trailer - 10=0x2
- break;
- }
- } // end of loop over clusters
-
- HLTDebug("Number of found clusters: %d", nAddedClusters);
+ outPtr->fSpacePointCnt++;
+ } // end of loop over clusters
+ }
+ HLTDebug("Number of found clusters: %d", outPtr->fSpacePointCnt);
- outPtr->fSpacePointCnt = nAddedClusters;
-
UInt_t mysize = sizeof(AliHLTTPCClusterData) + sizeof(AliHLTTPCSpacePointData)*outPtr->fSpacePointCnt;
AliHLTComponentBlockData bd;
size += mysize;
outputPtr += mysize;
- } // end of loop over data blocks
+ if (fPublishRawClusters) {
+
+ long maxRawClusters = ((long)maxOutSize-size-sizeof(AliHLTTPCRawClusterData))/sizeof(AliHLTTPCRawCluster);
+
+ if( maxRawClusters<=0 ) {
+ HLTWarning("No more space to add raw clusters, exiting!");
+ iResult = -ENOSPC;
+ } else {
+
+ // copy raw cluster data from input
+
+ AliHLTTPCRawClusterData* outputRaw= (AliHLTTPCRawClusterData*)(outputPtr);
+
+ outputRaw->fVersion = 0;
+ outputRaw->fCount = 0;
+
+ // check if there are clusters available, if not the format might
+ // not even been decoded at that moment
+ if (fpDecoder->GetNumberOfClusters()>0) {
+ for (AliHLTTPCHWCFData::iterator cl=fpDecoder->begin(); cl!=fpDecoder->end(); ++cl) {
+ if(outputRaw->fCount>=maxRawClusters){
+ HLTWarning("No more space to add clusters, exiting!");
+ iResult = -ENOSPC;
+ break;
+ }
+ AliHLTTPCRawCluster &c = outputRaw->fClusters[outputRaw->fCount];
+ int padrow=cl.GetPadRow();
+ if (padrow<0) {
+ // something wrong here, padrow is stored in the cluster header
+ // word which has bit pattern 0x3 in bits bit 30 and 31 which was
+ // not recognized
+ break;
+ }
+ padrow+=AliHLTTPCTransform::GetFirstRow(minPartition);
+ AliHLTUInt32_t charge= cl.GetCharge();
+
+ float pad =cl.GetPad();
+ float time =cl.GetTime();
+ float sigmaP2=cl.GetSigmaY2();
+ float sigmaT2=cl.GetSigmaZ2();
+ c.SetPadRow(padrow);
+ c.SetCharge(charge);
+ c.SetPad(pad);
+ c.SetTime(time);
+ c.SetSigmaY2(sigmaP2);
+ c.SetSigmaZ2(sigmaT2);
+ c.SetQMax(cl.GetQMax());
+
+ // store cluster and continue
+ outputRaw->fCount++;
+ }
+ }
+
+ // fill into HLT output data
+ AliHLTComponentBlockData bdRawClusters;
+ FillBlockData( bdRawClusters );
+ bdRawClusters.fOffset = size;
+ bdRawClusters.fSize = sizeof(AliHLTTPCRawClusterData)+outputRaw->fCount*sizeof(AliHLTTPCRawCluster);
+ bdRawClusters.fSpecification = iter->fSpecification;
+ bdRawClusters.fDataType = AliHLTTPCDefinitions::fgkRawClustersDataType | kAliHLTDataOriginTPC;
+ outputBlocks.push_back( bdRawClusters );
+ fBenchmark.AddOutput(bdRawClusters.fSize);
+ size += bdRawClusters.fSize;
+ outputPtr += bdRawClusters.fSize;
+ }
+ }
+ } // end of loop over data blocks
fBenchmark.Stop(0);
HLTInfo(fBenchmark.GetStatistics());
-
+
return iResult;
} // end DoEvent()
if (argument.CompareTo("-charge-threshold")==0) {
if (++i>=argc) return -EPROTO;
- argument=argv[i];
- fChargeThreshold=(UInt_t)argument.Atoi();
- HLTInfo("The charge threshold has been set to %d.", fChargeThreshold);
+ argument=argv[i];
+ HLTInfo("The argument -charge-threshold is deprecated.");
return 2;
}
+ if (argument.CompareTo("-publish-raw")==0) {
+ fPublishRawClusters=kTRUE;
+ return 1;
+ }
+
// unknown argument
return -EINVAL;
}
// OCDB entries to be fetched by the TAXI (access via the AliTPCcalibDB class)
targetMap->Add(new TObjString("TPC/Calib/Parameters"), new TObjString("unknown content"));
targetMap->Add(new TObjString("TPC/Calib/TimeDrift"), new TObjString("drift velocity calibration"));
+ targetMap->Add(new TObjString("TPC/Calib/TimeGain"), new TObjString("time gain calibration"));
targetMap->Add(new TObjString("TPC/Calib/Temperature"), new TObjString("temperature map"));
targetMap->Add(new TObjString("TPC/Calib/PadGainFactor"), new TObjString("gain factor pad by pad"));
targetMap->Add(new TObjString("TPC/Calib/ClusterParam"), new TObjString("cluster parameters"));
-
+ targetMap->Add(new TObjString("TPC/Calib/Correction"), new TObjString("coreection"));
+ targetMap->Add(new TObjString("TPC/Calib/RecoParam"), new TObjString("reconstruction parameters"));
+
// OCDB entries needed to be fetched by the Pendolino
targetMap->Add(new TObjString("TPC/Calib/AltroConfig"), new TObjString("contains the altro config, e.g. info about the L0 trigger timing"));
targetMap->Add(new TObjString("GRP/CTP/CTPtiming"), new TObjString("content used in the cluster coordinate transformation in relation to the L0 trigger timing"));
targetMap->Add(new TObjString("GRP/GRP/Data"), new TObjString("contains magnetic field info"));
// OCDB entries needed to suppress fatals/errors/warnings during reconstruction
+ targetMap->Add(new TObjString("TPC/Calib/Distortion"), new TObjString("distortion map"));
+ targetMap->Add(new TObjString("TPC/Calib/GainFactorDedx"), new TObjString("gain factor dedx"));
targetMap->Add(new TObjString("TPC/Calib/PadTime0"), new TObjString("time0 offset pad by pad"));
targetMap->Add(new TObjString("TPC/Calib/PadNoise"), new TObjString("pad noise values"));
targetMap->Add(new TObjString("TPC/Calib/Pedestals"), new TObjString("pedestal info"));