X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=HLT%2Fglobal%2FAliHLTGlobalEsdConverterComponent.cxx;h=413403f377f78267286a5f9917ef018f6a61d5c5;hb=8b15ecc341f56e9d8b80507b8fabbd0ee87f9a25;hp=59ff18a436ff1a2d69d0bd081c4426f01f7118b2;hpb=6117ef6316d24c87a2af9672f1963646f58f0026;p=u%2Fmrichter%2FAliRoot.git diff --git a/HLT/global/AliHLTGlobalEsdConverterComponent.cxx b/HLT/global/AliHLTGlobalEsdConverterComponent.cxx index 59ff18a436f..413403f377f 100644 --- a/HLT/global/AliHLTGlobalEsdConverterComponent.cxx +++ b/HLT/global/AliHLTGlobalEsdConverterComponent.cxx @@ -16,11 +16,11 @@ //* provided "as is" without express or implied warranty. * //************************************************************************** -/** @file AliHLTGlobalEsdConverterComponent.cxx - @author Matthias Richter - @date - @brief Global ESD converter component. -*/ +// @file AliHLTGlobalEsdConverterComponent.cxx +// @author Matthias Richter +// @date +// @brief Global ESD converter component. +// // see header file for class documentation // or @@ -34,17 +34,35 @@ #include "AliHLTExternalTrackParam.h" #include "AliHLTTrackMCLabel.h" #include "AliHLTCTPData.h" +#include "AliHLTTPCDefinitions.h" +#include "AliHLTTPCSpacePointData.h" +#include "AliHLTTPCClusterDataFormat.h" +#include "AliTPCclusterMI.h" +#include "AliTPCseed.h" +#include "AliESDfriend.h" +#include "AliESDfriendTrack.h" +#include "AliHLTTPCTransform.h" +#include "AliHLTErrorGuard.h" #include "AliESDEvent.h" #include "AliESDtrack.h" +#include "AliESDMuonTrack.h" +#include "AliESDMuonCluster.h" #include "AliCDBEntry.h" #include "AliCDBManager.h" #include "AliPID.h" #include "TTree.h" #include "TList.h" +#include "TClonesArray.h" +#include "TTimeStamp.h" +#include "THnSparse.h" #include "AliHLTESDCaloClusterMaker.h" #include "AliHLTCaloClusterDataStruct.h" #include "AliHLTCaloClusterReader.h" #include "AliESDCaloCluster.h" +#include "AliESDVZERO.h" +#include "AliHLTGlobalVertexerComponent.h" +#include "AliHLTVertexFinderBase.h" +#include "AliSysInfo.h" /** ROOT macro for the implementation of ROOT specific class methods */ ClassImp(AliHLTGlobalEsdConverterComponent) @@ -54,20 +72,30 @@ AliHLTGlobalEsdConverterComponent::AliHLTGlobalEsdConverterComponent() , fWriteTree(0) , fVerbosity(0) , fESD(NULL) - , fSolenoidBz(5) + , fESDfriend(NULL) + , fSolenoidBz(-5.00668) + , fMakeFriends(1) + , fBenchmark("EsdConverter") { // see header file for class documentation // or // refer to README to build package // or // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt + for( int i=0; iGetEntries() && iResult>=0; i++) { - argument=((TObjString*)pTokens->At(i))->GetString(); + argument=((TObjString*)pTokens->At(i))->String(); if (argument.IsNull()) continue; if (argument.CompareTo("-solenoidBz")==0) { if ((bMissingParam=(++i>=pTokens->GetEntries()))) break; - HLTInfo("Magnetic Field set to: %s", ((TObjString*)pTokens->At(i))->GetString().Data()); - fSolenoidBz=((TObjString*)pTokens->At(i))->GetString().Atof(); + HLTWarning("argument -solenoidBz is deprecated, magnetic field set up globally (%f)", GetBz()); continue; } else { HLTError("unknown argument %s", argument.Data()); @@ -111,7 +138,7 @@ int AliHLTGlobalEsdConverterComponent::Reconfigure(const char* cdbEntry, const c { // see header file for class documentation int iResult=0; - const char* path=kAliHLTCDBSolenoidBz; + const char* path=NULL; const char* defaultNotify=""; if (cdbEntry) { path=cdbEntry; @@ -123,8 +150,8 @@ int AliHLTGlobalEsdConverterComponent::Reconfigure(const char* cdbEntry, const c if (pEntry) { TObjString* pString=dynamic_cast(pEntry->GetObject()); if (pString) { - HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data()); - iResult=Configure(pString->GetString().Data()); + HLTInfo("received configuration object string: \'%s\'", pString->String().Data()); + iResult=Configure(pString->String().Data()); } else { HLTError("configuration object \"%s\" has wrong type, required TObjString", path); } @@ -142,12 +169,31 @@ void AliHLTGlobalEsdConverterComponent::GetInputDataTypes(AliHLTComponentDataTyp list.push_back(kAliHLTDataTypeTrack); list.push_back(kAliHLTDataTypeTrackMC); list.push_back(kAliHLTDataTypeCaloCluster); + list.push_back(kAliHLTDataTypedEdx ); + list.push_back(kAliHLTDataTypeESDVertex ); + list.push_back(kAliHLTDataTypeESDObject); + list.push_back(kAliHLTDataTypeTObject); + list.push_back(kAliHLTDataTypeGlobalVertexer); + list.push_back(kAliHLTDataTypeV0Finder); // array of track ids for V0s + list.push_back(kAliHLTDataTypeKFVertex); // KFVertex object from vertexer + list.push_back(kAliHLTDataTypePrimaryFinder); // array of track ids for prim vertex + list.push_back(kAliHLTDataTypeESDContent); + list.push_back( AliHLTTPCDefinitions::fgkClustersDataType ); } AliHLTComponentDataType AliHLTGlobalEsdConverterComponent::GetOutputDataType() { // see header file for class documentation - return kAliHLTDataTypeESDObject|kAliHLTDataOriginOut; + return kAliHLTMultipleDataType; +} + +int AliHLTGlobalEsdConverterComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList){ +// see header file for class documentation + + tgtList.clear(); + tgtList.push_back( kAliHLTDataTypeESDObject|kAliHLTDataOriginOut ); + tgtList.push_back( kAliHLTDataTypeESDfriendObject|kAliHLTDataOriginOut ); + return tgtList.size(); } void AliHLTGlobalEsdConverterComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier) @@ -163,21 +209,61 @@ int AliHLTGlobalEsdConverterComponent::DoInit(int argc, const char** argv) int iResult=0; TString argument=""; int bMissingParam=0; - for (int i=0; i=0; i++) { - argument=argv[i]; - if (argument.IsNull()) continue; - // -notree - if (argument.CompareTo("-notree")==0) { - fWriteTree=0; + // default list of skiped ESD objects + TString skipObjects= + // "AliESDRun," + // "AliESDHeader," + // "AliESDZDC," + "AliESDFMD," + // "AliESDVZERO," + // "AliESDTZERO," + // "TPCVertex," + // "SPDVertex," + // "PrimaryVertex," + // "AliMultiplicity," + // "PHOSTrigger," + // "EMCALTrigger," + // "SPDPileupVertices," + // "TrkPileupVertices," + "Cascades," + "Kinks," + "AliRawDataErrorLogs," + "AliESDACORDE"; - // -tree - } else if (argument.CompareTo("-tree")==0) { - fWriteTree=1; + iResult=Reconfigure(NULL, NULL); + TString allArgs = ""; + for ( int i = 0; i < argc; i++ ) { + if ( !allArgs.IsNull() ) allArgs += " "; + allArgs += argv[i]; + } - } else { - HLTError("unknown argument %s", argument.Data()); - break; + TObjArray* pTokens=allArgs.Tokenize(" "); + if (pTokens) { + for (int i=0; iGetEntries() && iResult>=0; i++) { + argument=((TObjString*)pTokens->At(i))->String(); + if (argument.IsNull()) continue; + + // -notree + if (argument.CompareTo("-notree")==0) { + fWriteTree=0; + + // -tree + } else if (argument.CompareTo("-tree")==0) { + fWriteTree=1; + } else if (argument.CompareTo("-solenoidBz")==0) { + if ((bMissingParam=(++i>=pTokens->GetEntries()))) break; + HLTInfo("Magnetic Field set to: %s", ((TObjString*)pTokens->At(i))->String().Data()); + HLTWarning("argument '-solenoidBz' is deprecated, solenoid field initiaized from CDB settings"); + continue; + } else if (argument.Contains("-skipobject=")) { + argument.ReplaceAll("-skipobject=", ""); + skipObjects=argument; + } else { + HLTError("unknown argument %s", argument.Data()); + iResult=-EINVAL; + break; + } } } if (bMissingParam) { @@ -185,20 +271,52 @@ int AliHLTGlobalEsdConverterComponent::DoInit(int argc, const char** argv) iResult=-EINVAL; } - if (iResult>=0) { - iResult=Reconfigure(NULL, NULL); - } + fSolenoidBz=GetBz(); + + delete fESD; + fESD = NULL; + delete fESDfriend; + fESDfriend=0; if (iResult>=0) { fESD = new AliESDEvent; if (fESD) { fESD->CreateStdContent(); + + // remove some of the objects which are not needed + if (fESD->GetList() && !skipObjects.IsNull()) { + pTokens=skipObjects.Tokenize(","); + if (pTokens) { + const char* id=NULL; + TIter next(pTokens); + TObject* pObject=NULL; + while ((pObject=next())!=NULL) { + id=((TObjString*)pObject)->String().Data(); + TObject* pObj=fESD->GetList()->FindObject(id); + if (pObj) { + HLTDebug("removing object %s", id); + fESD->GetList()->Remove(pObj); + delete pObj; + } else { + HLTWarning("failed to remove object '%s' from ESD", id); + } + } + fESD->GetStdContent(); + delete pTokens; + } + } } else { iResult=-ENOMEM; } SetupCTPData(); } + + if( iResult>=0 && fMakeFriends ){ + fESDfriend = new AliESDfriend(); + } + + fBenchmark.SetTimer(0,"total"); return iResult; } @@ -206,21 +324,38 @@ int AliHLTGlobalEsdConverterComponent::DoInit(int argc, const char** argv) int AliHLTGlobalEsdConverterComponent::DoDeinit() { // see header file for class documentation - if (fESD) delete fESD; + delete fESD; fESD=NULL; - + delete fESDfriend; + fESDfriend = NULL; return 0; } -int AliHLTGlobalEsdConverterComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/, +int AliHLTGlobalEsdConverterComponent::DoEvent(const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData) { // see header file for class documentation int iResult=0; + + + AliSysInfo::AddStamp("DoEvent.Start", evtData.fStructSize); + + bool benchmark = true; + if (!fESD) return -ENODEV; - AliESDEvent* pESD = fESD; + if (!IsDataEvent()) return iResult; + fBenchmark.StartNewEvent(); + fBenchmark.Start(0); + for(Int_t i=0; iReset(); pESD->SetMagneticField(fSolenoidBz); pESD->SetRunNumber(GetRunNo()); @@ -231,12 +366,18 @@ int AliHLTGlobalEsdConverterComponent::DoEvent(const AliHLTComponentEventData& / const AliHLTCTPData* pCTPData=CTPData(); if (pCTPData) { - AliHLTUInt64_t mask=pCTPData->ActiveTriggers(trigData); + AliHLTTriggerMask_t mask=pCTPData->ActiveTriggers(trigData); for (int index=0; indexSetTriggerClass(pCTPData->Name(index), index); } - pESD->SetTriggerMask(mask); + //first 50 triggers + AliHLTTriggerMask_t mask50; + mask50.set(); // set all bits + mask50 >>= 50; // shift 50 right + pESD->SetTriggerMask((mask&mask50).to_ulong()); + //next 50 + pESD->SetTriggerMaskNext50((mask>>50).to_ulong()); } TTree* pTree = NULL; @@ -247,7 +388,9 @@ int AliHLTGlobalEsdConverterComponent::DoEvent(const AliHLTComponentEventData& / pTree->SetDirectory(0); } - if ((iResult=ProcessBlocks(pTree, pESD))>=0) { + if( fESDfriend ) fESDfriend->Reset(); + + if ((iResult=ProcessBlocks(pTree, pESD, fESDfriend))>=0) { // TODO: set the specification correctly if (pTree) { // the esd structure is written to the user info and is @@ -258,38 +401,170 @@ int AliHLTGlobalEsdConverterComponent::DoEvent(const AliHLTComponentEventData& / } else { iResult=PushBack(pESD, kAliHLTDataTypeESDObject|kAliHLTDataOriginOut, 0); } + fBenchmark.AddOutput(GetLastObjectSize()); + if( iResult>=0 && fMakeFriends ){ + iResult=PushBack(fESDfriend, kAliHLTDataTypeESDfriendObject|kAliHLTDataOriginOut, 0); + fBenchmark.AddOutput(GetLastObjectSize()); + } } if (pTree) { // clear user info list to prevent objects from being deleted pTree->GetUserInfo()->Clear(); delete pTree; } + + fBenchmark.Stop(0); + HLTWarning( fBenchmark.GetStatistics() ); + + + + + + + if(benchmark){ + + Int_t nV0s = pESD->GetNumberOfV0s(); + Int_t nTracks = pESD->GetNumberOfTracks(); + + + Double_t statistics[10]; + TString names[10]; + fBenchmark.GetStatisticsData(statistics, names); + // statistics[5] = nTracks; + // statistics[6] = time; + // statistics[7] = nV0s; + + // FillBenchmarkHistos( statistics, names); + fBenchmark.Reset(); + + AliSysInfo::AddStamp("DoEvent.Stop", (int)(statistics[1]), (int)(statistics[2]),pESD->GetNumberOfV0s(),pESD->GetNumberOfTracks() ); + } + + for(Int_t i=0; iReset(); + if( fESD ) fESD->Reset(); + return iResult; } -int AliHLTGlobalEsdConverterComponent::ProcessBlocks(TTree* pTree, AliESDEvent* pESD) +int AliHLTGlobalEsdConverterComponent::ProcessBlocks(TTree* pTree, AliESDEvent* pESD, AliESDfriend *pESDfriend ) { // see header file for class documentation int iResult=0; int iAddedDataBlocks=0; + // check if there is an ESD block in the input and copy its content first to the + // ESD + const TObject* pEsdObj = GetFirstInputObject(kAliHLTDataTypeESDObject, "AliESDEvent"); + AliESDEvent* pInputESD=NULL; + if (pEsdObj) pInputESD=dynamic_cast(const_cast(pEsdObj)); + if (pInputESD) { + pInputESD->GetStdContent(); + *pESD=*pInputESD; + } + if (GetNextInputObject()!=NULL) { + HLTWarning("handling of multiple ESD input objects not implemented, skipping input"); + } + // Barrel tracking + // tracks are based on the TPC tracks, and only updated from the ITS information + // Sequence: + // 1) extract MC information for TPC and ITS from specific data blocks and store in + // intermediate vector arrays + // 2) extract TPC tracks, update with MC labels if available, the track parameters + // are estimated at the first cluster position + // 2.1) propagate to last cluster position and update kTPCout, sets also outer param (fOp) + // 2.2) update kTPCin, sets also inner param (fIp) and TPC inner param (fTPCInner) + // 2.3) update kTPCrefit using the same parameters at the first cluster position + // HLT has strictly spoking no refit, but we want the flag to be set + // can be changed to be done after all the individual barrel detector parameters + // have been updated by looping over the tracks again + // 3) extract ITS tracks, the tracks are actually TPC tracks updated from the ITS + // tracking information + // 3.1) TODO 2010-07-12: handle ITS standalone tracks by updating kITSout before kITSin + // 3.2) update with kITSin + // TODO 2010-07-12 find out if the kITSrefit has to be set as well + // 4) extract TRD tracks and add to ESD + // TODO 2010-07-12 at the moment there is no matching or merging of TPC and TRD tracks + // 5) Add Trigger Detectors + // VZERO, ZDC - // in the first attempt this component reads the TPC tracks and updates in the - // second step from the ITS tracks + // read the clusters + // ---------- Access to clusters --------------------// + for(Int_t i=0; i mcLabels; + if( pESDfriend ){ + + int nInputClusters = 0; + + for(const AliHLTComponentBlockData *iter = GetFirstInputBlock(AliHLTTPCDefinitions::fgkClustersDataType); iter != NULL; iter = GetNextInputBlock()){ + + if(iter->fDataType != AliHLTTPCDefinitions::fgkClustersDataType) continue; + Int_t slice = AliHLTTPCDefinitions::GetMinSliceNr(iter->fSpecification); + Int_t partition = AliHLTTPCDefinitions::GetMinPatchNr(iter->fSpecification); + Int_t slicepartition = slice*6+partition; + if(slicepartition<0 || slicepartition > fkNPartition){ + HLTWarning("Wrong header of TPC cluster data, slice %d, partition %d", slice, partition ); + continue; + } + + AliHLTTPCClusterData *inPtrSP = ( AliHLTTPCClusterData* )( iter->fPtr ); + nInputClusters += inPtrSP->fSpacePointCnt; + + delete[] fPartitionClusters[slicepartition]; + fPartitionClusters[slicepartition] = new AliTPCclusterMI[inPtrSP->fSpacePointCnt]; + fNPartitionClusters[slicepartition] = inPtrSP->fSpacePointCnt; + + // create offline clusters out of the HLT clusters + + for ( unsigned int i = 0; i < inPtrSP->fSpacePointCnt; i++ ) { + AliHLTTPCSpacePointData *chlt = &( inPtrSP->fSpacePoints[i] ); + AliTPCclusterMI *c = fPartitionClusters[slicepartition]+i; + c->SetX(chlt->fX); + c->SetY(chlt->fY); + c->SetZ(chlt->fZ); + c->SetSigmaY2(chlt->fSigmaY2); + c->SetSigmaYZ( 0 ); + c->SetSigmaZ2(chlt->fSigmaZ2); + c->SetQ( chlt->fCharge ); + c->SetMax( chlt->fQMax ); + Int_t sector, row; + Float_t padtime[3] = {0,chlt->fY,chlt->fZ}; + AliHLTTPCTransform::Slice2Sector(slice,chlt->fPadRow, sector, row); + AliHLTTPCTransform::Local2Raw( padtime, sector, row); + c->SetDetector( sector ); + c->SetRow( row ); + c->SetPad( (Int_t) padtime[1] ); + c->SetTimeBin( (Int_t) padtime[2] ); + } + } // end of loop over blocks of clusters + } + + // 1) first read MC information (if present) + std::map mcLabelsTPC; + std::map mcLabelsITS; for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrackMC|kAliHLTDataOriginTPC); pBlock!=NULL; pBlock=GetNextInputBlock()) { + + fBenchmark.AddInput(pBlock->fSize); + AliHLTTrackMCData* dataPtr = reinterpret_cast( pBlock->fPtr ); if (sizeof(AliHLTTrackMCData)+dataPtr->fCount*sizeof(AliHLTTrackMCLabel)==pBlock->fSize) { for( unsigned int il=0; ilfCount; il++ ){ AliHLTTrackMCLabel &lab = dataPtr->fLabels[il]; - mcLabels[lab.fTrackID] = lab.fMCLabel; + mcLabelsTPC[lab.fTrackID] = lab.fMCLabel; } } else { HLTWarning("data mismatch in block %s (0x%08x): count %d, size %d -> ignoring track MC information", @@ -297,24 +572,59 @@ int AliHLTGlobalEsdConverterComponent::ProcessBlocks(TTree* pTree, AliESDEvent* dataPtr->fCount, pBlock->fSize); } } + + for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrackMC|kAliHLTDataOriginITS); + pBlock!=NULL; pBlock=GetNextInputBlock()) { + + fBenchmark.AddInput(pBlock->fSize); + + AliHLTTrackMCData* dataPtr = reinterpret_cast( pBlock->fPtr ); + if (sizeof(AliHLTTrackMCData)+dataPtr->fCount*sizeof(AliHLTTrackMCLabel)==pBlock->fSize) { + for( unsigned int il=0; ilfCount; il++ ){ + AliHLTTrackMCLabel &lab = dataPtr->fLabels[il]; + mcLabelsITS[lab.fTrackID] = lab.fMCLabel; + } + } else { + HLTWarning("data mismatch in block %s (0x%08x): count %d, size %d -> ignoring track MC information", + DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification, + dataPtr->fCount, pBlock->fSize); + } + } + + + // read dEdx information (if present) + // TODO 2010-07-12 this needs to be verified + + AliHLTFloat32_t *dEdxTPC = 0; + Int_t ndEdxTPC = 0; + for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypedEdx|kAliHLTDataOriginTPC); + pBlock!=NULL; pBlock=NULL/*GetNextInputBlock() there is only one block*/) { + fBenchmark.AddInput(pBlock->fSize); + dEdxTPC = reinterpret_cast( pBlock->fPtr ); + ndEdxTPC = pBlock->fSize / (3*sizeof(AliHLTFloat32_t)); + } - // convert the TPC tracks to ESD tracks + // 2) convert the TPC tracks to ESD tracks for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC); pBlock!=NULL; pBlock=GetNextInputBlock()) { + if (pInputESD && pInputESD->GetNumberOfTracks()>0) { + HLTWarning("Tracks array already filled from the input esd block, additional filling from TPC tracks block might cause inconsistent content"); + } + fBenchmark.AddInput(pBlock->fSize); vector tracks; if ((iResult=AliHLTGlobalBarrelTrack::ConvertTrackDataArray(reinterpret_cast(pBlock->fPtr), pBlock->fSize, tracks))>=0) { for (vector::iterator element=tracks.begin(); element!=tracks.end(); element++) { Float_t points[4] = { - element->GetX(), - element->GetY(), - element->GetLastPointX(), - element->GetLastPointY() + static_cast(element->GetX()), + static_cast(element->GetY()), + static_cast(element->GetLastPointX()), + static_cast(element->GetLastPointY()) }; Int_t mcLabel = -1; - if( mcLabels.find(element->TrackID())!=mcLabels.end() ) - mcLabel = mcLabels[element->TrackID()]; + if( mcLabelsTPC.find(element->TrackID())!=mcLabelsTPC.end() ) + mcLabel = mcLabelsTPC[element->TrackID()]; element->SetLabel( mcLabel ); AliESDtrack iotrack; @@ -327,14 +637,118 @@ int AliHLTGlobalEsdConverterComponent::ProcessBlocks(TTree* pTree, AliESDEvent* // pid signal // The first one can be updated already at that stage here, while the two others // eventually require to update from the ITS tracks before. The exact scheme - // needs to be checked + // needs to be checked + iotrack.SetID( element->TrackID() ); + + // 2.1 set kTPCout + // TODO 2010-07-12 disabled for the moment because of bug + // https://savannah.cern.ch/bugs/index.php?69875 + // the propagation does not work, there is an offset in z + // propagate to last cluster and update parameters with flag kTPCout + // Note: updating with flag kITSout further down will overwrite the outer + // parameter again so this can be done only for ITS standalone tracks, meaning + // tracks in the ITS not associated with any TPC track + // HLT does not provide such standalone tracking + { + AliHLTGlobalBarrelTrack outPar(*element); + //outPar.AliExternalTrackParam::PropagateTo( element->GetLastPointX(), fSolenoidBz ); + const Int_t N=10; // number of steps. + const Float_t xRange = element->GetLastPointX() - element->GetX(); + const Float_t xStep = xRange / N ; + for(int i = 1; i <= N; ++i) { + if(!outPar.AliExternalTrackParam::PropagateTo(element->GetX() + xStep * i, fSolenoidBz)) break; + } + outPar.SetLabel(element->GetLabel()); + iotrack.UpdateTrackParams(&outPar,AliESDtrack::kTPCout); + } + // 2.2 TPC tracking estimates parameters at first cluster iotrack.UpdateTrackParams(&(*element),AliESDtrack::kTPCin); - iotrack.UpdateTrackParams(&(*element),AliESDtrack::kTPCout); - iotrack.SetTPCPoints(points); + // 2.3 use the same parameters also for kTPCrefit, there is no proper refit in HLT + // maybe this can be done later, however also the inner parameter is changed which + // is used as a reference point in the display. That point should be at the first + // TPC cluster + iotrack.UpdateTrackParams(&(*element),AliESDtrack::kTPCrefit); + iotrack.SetTPCPoints(points); + if( element->TrackID()TrackID()]); + iotrack.SetTPCsignal( val[0], val[1], (UChar_t) val[2] ); + //AliTPCseed s; + //s.Set( element->GetX(), element->GetAlpha(), + //element->GetParameter(), element->GetCovariance() ); + //s.SetdEdx( val[0] ); + //s.CookPID(); + //iotrack.SetTPCpid(s.TPCrPIDs() ); + } else { + if( dEdxTPC ) HLTWarning("Wrong number of dEdx TPC labels"); + } + iotrack.SetLabel(mcLabel); pESD->AddTrack(&iotrack); if (fVerbosity>0) element->Print(); + + if( pESDfriend ){ // create friend track + + AliHLTGlobalBarrelTrack gb(*element); + AliTPCseed tTPC; + tTPC.Set( gb.GetX(), gb.GetAlpha(), gb.GetParameter(), gb.GetCovariance() ); + tTPC.SetLabel(mcLabel); + + // set the clusters + UInt_t nClusters = element->GetNumberOfPoints(); + const UInt_t*clusterIDs = element->GetPoints(); + + tTPC.SetNumberOfClusters(nClusters); + + for(UInt_t ic=0; ic36 || iPartition<0 || iPartition>5){ + HLTError("Corrupted TPC cluster Id: slice %d, partition %d, cluster %d", iSlice, iPartition, iCluster); + continue; + } + + AliTPCclusterMI *patchClusters = fPartitionClusters[iSlice*6 + iPartition]; + if(!patchClusters){ + HLTError("Clusters are missed for slice %d, partition %d", iSlice, iPartition ); + continue; + } + + if(iCluster >= fNPartitionClusters[iSlice*6 + iPartition]){ + HLTError("TPC slice %d, partition %d: ClusterID==%d >= N Cluaters==%d ", iSlice, iPartition,iCluster, fNPartitionClusters[iSlice*6 + iPartition] ); + continue; + } + + AliTPCclusterMI *c = &(patchClusters[iCluster]); + int sec = c->GetDetector(); + int row = c->GetRow(); + if(sec >= 36) row = row + AliHLTTPCTransform::GetNRowLow(); + + tTPC.SetClusterPointer(row, c); + + AliTPCTrackerPoint &point = *( tTPC.GetTrackPoint( row ) ); + //tTPC.Propagate( TMath::DegToRad()*(sec%18*20.+10.), c->GetX(), fSolenoidBz ); + Double_t angle2 = tTPC.GetSnp()*tTPC.GetSnp(); + angle2 = (angle2<1) ?TMath::Sqrt(angle2/(1-angle2)) :10.; + point.SetAngleY( angle2 ); + point.SetAngleZ( tTPC.GetTgl() ); + } // end of associated cluster loop + + // Cook dEdx + + AliTPCseed *seed = &(tTPC); + //fSeedArray->AddAt( seed, TMath::Abs(seed->GetLabel()) ); + //fdEdx->Fill( seed->P()*seed->Charge(), seed->CookdEdx(0.02, 0.6) ); + + AliESDfriendTrack friendTrack; + friendTrack.AddCalibObject(&tTPC); + pESDfriend->AddTrack(&friendTrack); + } } + HLTInfo("converted %d track(s) to AliESDtrack and added to ESD", tracks.size()); iAddedDataBlocks++; } else if (iResult<0) { @@ -343,35 +757,154 @@ int AliHLTGlobalEsdConverterComponent::ProcessBlocks(TTree* pTree, AliESDEvent* } } - // now update ESD tracks with the ITS info - for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginITS); + + // Get ITS SPD vertex + for( const AliHLTComponentBlockData *i= GetFirstInputBlock(kAliHLTDataTypeESDVertex|kAliHLTDataOriginITS); i!=NULL; i=GetNextInputBlock() ){ + fBenchmark.AddInput(i->fSize); + } + + for ( const TObject *iter = GetFirstInputObject(kAliHLTDataTypeESDVertex|kAliHLTDataOriginITS); iter != NULL; iter = GetNextInputObject() ) { + AliESDVertex *vtx = dynamic_cast(const_cast( iter ) ); + pESD->SetPrimaryVertexSPD( vtx ); + } + + // 3.1. now update ESD tracks with the ITSOut info + // updating track parameters with flag kITSout will overwrite parameter set above with flag kTPCout + // TODO 2010-07-12 there are some issues with this updating sequence, for the moment update with + // flag kITSout is disabled, would require + // a) to update kTPCout after kITSout + // b) update only for ITS standalone tracks. The HLT ITS tracker does not provide standalone + // tracking, every track is related to a TPC track + // Furthermore there seems to be a bug as the data blocks describe track parameters around the + // vertex, not at the outer ITS + // bug https://savannah.cern.ch/bugs/index.php?69872 + for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginITSOut); pBlock!=NULL; pBlock=GetNextInputBlock()) { + fBenchmark.AddInput(pBlock->fSize); vector tracks; if ((iResult=AliHLTGlobalBarrelTrack::ConvertTrackDataArray(reinterpret_cast(pBlock->fPtr), pBlock->fSize, tracks))>0) { for (vector::iterator element=tracks.begin(); element!=tracks.end(); element++) { - int ncl=0; - const UInt_t* pointsArray=element->GetPoints(); - for( unsigned il=0; ilGetNumberOfPoints(); il++ ){ - // TODO: check what needs to be done with the clusters - if( pointsArray[il]<~(UInt_t)0 ) {/*tITS.SetClusterIndex(ncl, tr.fClusterIds[il]);*/} - ncl++; - } - //tITS.SetNumberOfClusters( ncl ); int tpcID=element->TrackID(); // the ITS tracker assigns the TPC track used as seed for a certain track to // the trackID if( tpcID<0 || tpcID>=pESD->GetNumberOfTracks()) continue; + AliESDtrack *tESD = pESD->GetTrack( tpcID ); + element->SetLabel(tESD->GetLabel()); + // 2010-07-12 disabled, see above, bugfix https://savannah.cern.ch/bugs/index.php?69872 + //if( tESD ) tESD->UpdateTrackParams( &(*element), AliESDtrack::kITSout ); + } + } + } + // 3.2. now update ESD tracks with the ITS info + for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginITS); + pBlock!=NULL; pBlock=GetNextInputBlock()) { + fBenchmark.AddInput(pBlock->fSize); + vector tracks; + if ((iResult=AliHLTGlobalBarrelTrack::ConvertTrackDataArray(reinterpret_cast(pBlock->fPtr), pBlock->fSize, tracks))>0) { + for (vector::iterator element=tracks.begin(); + element!=tracks.end(); element++) { + int tpcID=element->TrackID(); + // the ITS tracker assigns the TPC track used as seed for a certain track to + // the trackID + if( tpcID<0 || tpcID>=pESD->GetNumberOfTracks()) continue; + Int_t mcLabel = -1; + if( mcLabelsITS.find(element->TrackID())!=mcLabelsITS.end() ) + mcLabel = mcLabelsITS[element->TrackID()]; AliESDtrack *tESD = pESD->GetTrack( tpcID ); - if( tESD ) tESD->UpdateTrackParams( &(*element), AliESDtrack::kITSin ); + if (!tESD) continue; + // the labels for the TPC and ITS tracking params can be different, e.g. + // there can be a decay. The ITS label should then be the better one, the + // TPC label is saved in a member of AliESDtrack + if (mcLabel>=0) { + // upadte only if the ITS label is available, otherwise keep TPC label + element->SetLabel( mcLabel ); + } else { + // bugfix https://savannah.cern.ch/bugs/?69713 + element->SetLabel( tESD->GetLabel() ); + } + tESD->UpdateTrackParams( &(*element), AliESDtrack::kITSin ); + + // TODO: add a proper refit + //tESD->UpdateTrackParams( &(*element), AliESDtrack::kTPCrefit ); } } } - // convert the HLT TRD tracks to ESD tracks + // update with vertices and vertex-fitted tracks + // output of the GlobalVertexerComponent + for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeGlobalVertexer); + pBlock!=NULL; pBlock=GetNextInputBlock()) { + fBenchmark.AddInput(pBlock->fSize); + AliHLTGlobalVertexerComponent::FillESD( pESD, reinterpret_cast(pBlock->fPtr) ); + } + + // update with vertices and vertex-fitted tracks + // output of PrimaryVertexer and V0Finder components + + TObject* pBase = (TObject*)GetFirstInputObject(kAliHLTDataTypeKFVertex | kAliHLTDataOriginOut); + if (pBase) { + AliKFVertex* kfVertex = dynamic_cast(pBase); + if (kfVertex) { + const AliHLTComponentBlockData* pP = GetFirstInputBlock(kAliHLTDataTypePrimaryFinder | kAliHLTDataOriginOut); + if (pP && pP->fSize && pP->fPtr) { + const AliHLTComponentBlockData* pV0 = GetFirstInputBlock(kAliHLTDataTypeV0Finder | kAliHLTDataOriginOut); + if (pV0 && pV0->fPtr && pInputESD && pInputESD->GetNumberOfV0s()>0) { + const int* v0s = static_cast(pV0->fPtr); + HLTWarning("V0 array already filled from the input esd block, additional filling from V0 block of %d entries might cause inconsistent content", v0s[0]); + } + AliHLTVertexFinderBase::FillESD(pESD, kfVertex, pP->fPtr, pV0?pV0->fPtr:NULL); + } else + HLTWarning("Problem with primary finder's data block"); + } else { + HLTWarning("primary vertex block of wrong type, expecting AliKFVertex instead of %s", pBase->GetName()); + } + } else { + // throw an error if there is a V0 data block which can not be handled without + // the AliKFVertex object + if (GetFirstInputBlock(kAliHLTDataTypeV0Finder | kAliHLTDataOriginOut)!=NULL) { + ALIHLTERRORGUARD(1, "missing AliKFVertex object ignoring V0 data block of type %s", + DataType2Text(kAliHLTDataTypeV0Finder|kAliHLTDataOriginOut).c_str()); + } + } + + // Fill DCA parameters for TPC tracks + // TODO 2010-07-12 this propagates also the TPC inner param to beamline + // sounds not very reasonable + // https://savannah.cern.ch/bugs/index.php?69873 + for (int i=0; iGetNumberOfTracks(); i++) { + if (!pESD->GetTrack(i) || + !pESD->GetTrack(i)->GetTPCInnerParam() ) continue; + pESD->GetTrack(i)->RelateToVertexTPC(pESD->GetPrimaryVertexTracks(), fSolenoidBz, 1000 ); + } + + // loop over all tracks and set the TPC refit flag by updating with the + // original TPC inner parameter if not yet set + // TODO: replace this by a proper refit + // code is comented for the moment as it does not fully solve the problems with + // the display + // - would set the main parameters to the TPC inner wall again, or + // - changes the inner param if the parameters are propagated, so we loose the track + // reference point for the display + // with the current sequence we have the latter case as the DCA operations above + // change the TPC inner parameters + /* + for (int i=0; iGetNumberOfTracks(); i++) { + if (!pESD->GetTrack(i) || + !pESD->GetTrack(i)->GetTPCInnerParam() || + pESD->GetTrack(i)->IsOn(AliESDtrack::kTPCrefit)) continue; + AliESDtrack* tESD=pESD->GetTrack(i); + AliHLTGlobalBarrelTrack inner(*tESD->GetTPCInnerParam()); + inner.SetLabel(tESD->GetLabel()); + tESD->UpdateTrackParams(&inner, AliESDtrack::kTPCrefit); + } + */ + + // 4. convert the HLT TRD tracks to ESD tracks for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeTrack | kAliHLTDataOriginTRD); pBlock!=NULL; pBlock=GetNextInputBlock()) { + fBenchmark.AddInput(pBlock->fSize); vector tracks; if ((iResult=AliHLTGlobalBarrelTrack::ConvertTrackDataArray(reinterpret_cast(pBlock->fPtr), pBlock->fSize, tracks))>0) { for (vector::iterator element=tracks.begin(); @@ -386,7 +919,8 @@ int AliHLTGlobalEsdConverterComponent::ProcessBlocks(TTree* pTree, AliESDEvent* } AliESDtrack iotrack; - iotrack.UpdateTrackParams(&(*element),AliESDtrack::kTRDin); + iotrack.UpdateTrackParams(&(*element),AliESDtrack::kTRDout); + iotrack.SetStatus(AliESDtrack::kTRDin); iotrack.SetTRDpid(TRDpid); pESD->AddTrack(&iotrack); @@ -399,34 +933,177 @@ int AliHLTGlobalEsdConverterComponent::ProcessBlocks(TTree* pTree, AliESDEvent* DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification, pBlock->fSize, iResult); } } - for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeCaloCluster | kAliHLTDataOriginPHOS); pBlock!=NULL; pBlock=GetNextInputBlock()) + for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeCaloCluster | kAliHLTDataOriginAny); pBlock!=NULL; pBlock=GetNextInputBlock()) { + fBenchmark.AddInput(pBlock->fSize); AliHLTCaloClusterHeaderStruct *caloClusterHeaderPtr = reinterpret_cast(pBlock->fPtr); HLTDebug("%d HLT clusters from spec: 0x%X", caloClusterHeaderPtr->fNClusters, pBlock->fSpecification); - AliHLTCaloClusterReader reader; - reader.SetMemory(caloClusterHeaderPtr); + //AliHLTCaloClusterReader reader; + //reader.SetMemory(caloClusterHeaderPtr); AliHLTESDCaloClusterMaker clusterMaker; int nClusters = clusterMaker.FillESD(pESD, caloClusterHeaderPtr); - + HLTInfo("converted %d cluster(s) to AliESDCaloCluster and added to ESD", nClusters); iAddedDataBlocks++; } - - // primary vertex & V0's - /* - //AliHLTVertexer vertexer; - //vertexer.SetESD( pESD ); - //vertexer.FindPrimaryVertex(); - //vertexer.FindV0s(); - */ - if (iAddedDataBlocks>0 && pTree) { - pTree->Fill(); + + // 5) Add Trigger Detectors + // VZERO, ZDC + + // FIXME: the size of all input blocks can be added in one loop + for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeESDContent|kAliHLTDataOriginVZERO); + pBlock!=NULL; pBlock=GetNextInputBlock()) { + fBenchmark.AddInput(pBlock->fSize); + } + + for ( const TObject *pObject = GetFirstInputObject(kAliHLTDataTypeESDContent|kAliHLTDataOriginVZERO); + pObject != NULL; pObject = GetNextInputObject() ) { + AliESDVZERO *esdVZERO = dynamic_cast(const_cast( pObject ) ); + if (esdVZERO) { + pESD->SetVZEROData( esdVZERO ); + break; + } else { + ALIHLTERRORGUARD(1, "input object of data type %s is not of class AliESDVZERO", + DataType2Text(kAliHLTDataTypeESDContent|kAliHLTDataOriginVZERO).c_str()); + } + } + + // FIXME: the size of all input blocks can be added in one loop + for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeESDContent|kAliHLTDataOriginZDC); + pBlock!=NULL; pBlock=GetNextInputBlock()) { + fBenchmark.AddInput(pBlock->fSize); + } + for ( const TObject *pObject = GetFirstInputObject(kAliHLTDataTypeESDContent|kAliHLTDataOriginZDC); + pObject != NULL; pObject = GetNextInputObject() ) { + AliESDZDC *esdZDC = dynamic_cast(const_cast( pObject ) ); + if (esdZDC) { +#ifndef HAVE_NOT_ALIZDCRECONSTRUCTOR_r43770 + pESD->SetZDCData( esdZDC ); +#else + ALIHLTERRORGUARD(1, "Processing of ZDC data requires AliRoot r43770m skipping data block of type %s", + DataType2Text(kAliHLTDataTypeESDContent|kAliHLTDataOriginZDC).c_str()); +#endif + break; + } else { + ALIHLTERRORGUARD(1, "input object of data type %s is not of class AliESDZDC", + DataType2Text(kAliHLTDataTypeESDContent|kAliHLTDataOriginZDC).c_str()); + } + } + + // Add tracks and clusters from MUON. + for( const AliHLTComponentBlockData *i= GetFirstInputBlock(kAliHLTAnyDataType | kAliHLTDataOriginMUON); i!=NULL; i=GetNextInputBlock() ){ + fBenchmark.AddInput(i->fSize); + } + + for (const TObject* obj = GetFirstInputObject(kAliHLTAnyDataType | kAliHLTDataOriginMUON); + obj != NULL; + obj = GetNextInputObject() + ) + { + const TClonesArray* tracklist = NULL; + const TClonesArray* clusterlist = NULL; + if (obj->IsA() == AliESDEvent::Class()) + { + const AliESDEvent* event = static_cast(obj); + HLTDebug("Received a MUON ESD with specification: 0x%X", GetSpecification(obj)); + if (event->GetList() == NULL) continue; + tracklist = dynamic_cast(event->GetList()->FindObject("MuonTracks")); + if (tracklist == NULL) continue; + clusterlist = dynamic_cast(event->GetList()->FindObject("MuonClusters")); + if (clusterlist == NULL) continue; + } + else if (obj->IsA() == TClonesArray::Class()) + { + if (!strcmp(obj->GetName(), "MuonTracks")) { + tracklist = static_cast(obj); + HLTDebug("Received a MUON TClonesArray of tracks with specification: 0x%X", GetSpecification(obj)); + } else { + clusterlist = static_cast(obj); + HLTDebug("Received a MUON TClonesArray of clusters with specification: 0x%X", GetSpecification(obj)); } + } + else + { + // Cannot handle this object type. + continue; + } + // copy tracks + if (tracklist) { + HLTDebug("Received %d MUON tracks.", tracklist->GetEntriesFast()); + if (tracklist->GetEntriesFast() > 0) + { + const AliESDMuonTrack* track = dynamic_cast(tracklist->UncheckedAt(0)); + if (track == NULL) + { + HLTError(Form("%s from MUON does not contain AliESDMuonTrack objects.", obj->ClassName())); + continue; + } + } + for (Int_t i = 0; i < tracklist->GetEntriesFast(); ++i) + { + AliESDMuonTrack* track = pESD->NewMuonTrack(); + *track = *(static_cast(tracklist->UncheckedAt(i))); + } + } + // copy clusters + if (clusterlist) { + HLTDebug("Received %d MUON clusters.", clusterlist->GetEntriesFast()); + if (clusterlist->GetEntriesFast() > 0) + { + const AliESDMuonCluster* cluster = dynamic_cast(clusterlist->UncheckedAt(0)); + if (cluster == NULL) + { + HLTError(Form("%s from MUON does not contain AliESDMuonCluster objects.", obj->ClassName())); + continue; + } + } + for (Int_t i = 0; i < clusterlist->GetEntriesFast(); ++i) + { + AliESDMuonCluster* cluster = pESD->NewMuonCluster(); + *cluster = *(static_cast(clusterlist->UncheckedAt(i))); + } + } + } + + if( fMakeFriends && pESDfriend ){ // create friend track + pESD->SetESDfriend( pESDfriend ); + } + + cout<<"\n\n ESD Friend: "<GetNumberOfTracks()<0 && pTree) { + pTree->Fill(); + } if (iResult>=0) iResult=iAddedDataBlocks; return iResult; } + + + +/* +void AliHLTGlobalEsdConverterComponent::FillBenchmarkHistos(Double_t *statistics, TString *names){ +return; + +// cout<<"Now writing benchmarks to " << fBenchmarkHistosFilename <Get("benchmarkInformation"); + TNamed *t = (TNamed*)f->Get("time"); + + if(!s){ + HLTWarning( "Benchmark Histograms not available!" ); + return; + } + s->Fill(statistics); + + TList histosList; + histosList.Add(s); + histosList.Add(t); + histosList.SaveAs(fBenchmarkHistosFilename); +} +*/