From bc5cb6d681a35f0cb537a8ac70616d80d5750257 Mon Sep 17 00:00:00 2001 From: aszostak Date: Mon, 23 Nov 2009 11:08:09 +0000 Subject: [PATCH] Important updates for Manso Tracker to use magnetic field integrals based on global field set in TGeoGlobalMagField or from GRP data. Now also optionally generating and rootifying track candidates for debugging. Some bug fixes for handling strip information in AliHLTMUONTriggerReconstructorComponent. Adding default field integrals and generation macro CreateCDBFieldIntegrals.C. Adding macro for displaying dHLT rootified output data DisplaydHLTData.C. --- HLT/MUON/AliHLTMUONConstants.cxx | 7 +- HLT/MUON/AliHLTMUONConstants.h | 6 + HLT/MUON/AliHLTMUONMansoTrack.cxx | 92 ++++++ HLT/MUON/AliHLTMUONMansoTrack.h | 40 +++ HLT/MUON/AliHLTMUONProcessor.cxx | 93 ++++++ HLT/MUON/AliHLTMUONProcessor.h | 11 + HLT/MUON/AliHLTMUONTriggerRecord.cxx | 23 +- .../AliHLTMUONRootifierComponent.cxx | 227 ++++++++------ .../AliHLTMUONRootifierComponent.h | 12 + .../OnlineAnalysis/AliHLTMUONCalculations.cxx | 58 +++- .../OnlineAnalysis/AliHLTMUONCalculations.h | 10 + .../AliHLTMUONMansoTrackerFSM.cxx | 170 ++++++++++- .../AliHLTMUONMansoTrackerFSM.h | 53 +++- .../AliHLTMUONMansoTrackerFSMComponent.cxx | 70 ++++- .../AliHLTMUONMansoTrackerFSMComponent.h | 7 +- .../AliHLTMUONTriggerReconstructor.cxx | 48 ++- ...liHLTMUONTriggerReconstructorComponent.cxx | 17 +- HLT/MUON/macros/CreateCDBFieldIntegrals.C | 168 +++++++++++ HLT/MUON/macros/CreateDefaultCDBEntries.C | 6 +- HLT/MUON/macros/DisplaydHLTData.C | 281 ++++++++++++++++++ HLT/MUON/macros/RunChain.C | 8 +- .../FieldIntegrals/Run0_999999999_v0_s0.root | Bin 0 -> 2603 bytes 22 files changed, 1255 insertions(+), 152 deletions(-) create mode 100644 HLT/MUON/macros/CreateCDBFieldIntegrals.C create mode 100644 HLT/MUON/macros/DisplaydHLTData.C create mode 100644 OCDB/HLT/ConfigMUON/FieldIntegrals/Run0_999999999_v0_s0.root diff --git a/HLT/MUON/AliHLTMUONConstants.cxx b/HLT/MUON/AliHLTMUONConstants.cxx index ca4eaaf2298..6a7f7216aa9 100644 --- a/HLT/MUON/AliHLTMUONConstants.cxx +++ b/HLT/MUON/AliHLTMUONConstants.cxx @@ -50,7 +50,10 @@ AliHLTMUONConstants::fgkNilTriggerRecordStruct = { }; const AliHLTMUONTrigRecInfoStruct -AliHLTMUONConstants::fgkNilTrigRecInfoStruct = {0, {0, 0, 0, 0}, 0, 0, {0, 0, 0, 0, 0}}; +AliHLTMUONConstants::fgkNilTrigRecInfoStruct = { + 0, {0, 0, 0, 0}, 0, 0, + {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} +}; const AliHLTMUONRecHitStruct AliHLTMUONConstants::fgkNilRecHitStruct = {0, 0, 0, 0}; @@ -157,4 +160,4 @@ const char* AliHLTMUONConstants::fgkTriggerReconstructorCDBPath = "HLT/ConfigMUO const char* AliHLTMUONConstants::fgkHitReconstructorCDBPath = "HLT/ConfigMUON/HitReconstructor"; const char* AliHLTMUONConstants::fgkMansoTrackerFSMCDBPath = "HLT/ConfigMUON/MansoTrackerFSM"; const char* AliHLTMUONConstants::fgkDecisionComponentCDBPath = "HLT/ConfigMUON/DecisionComponent"; - +const char* AliHLTMUONConstants::fgkFieldIntegralsCDBPath = "HLT/ConfigMUON/FieldIntegrals"; diff --git a/HLT/MUON/AliHLTMUONConstants.h b/HLT/MUON/AliHLTMUONConstants.h index 215a6d3ee65..955ba492e23 100644 --- a/HLT/MUON/AliHLTMUONConstants.h +++ b/HLT/MUON/AliHLTMUONConstants.h @@ -268,6 +268,11 @@ public: return fgkDecisionComponentCDBPath; } + static const char* FieldIntegralsCDBPath() + { + return fgkFieldIntegralsCDBPath; + } + /// Returns the typical X (non-bending plane) resolution of the hit reconstruction (units = cm). static double DefaultNonBendingReso() { return 0.144; } @@ -332,6 +337,7 @@ private: static const char* fgkHitReconstructorCDBPath; // Path to CDB entry for the hit reconstruction component. static const char* fgkMansoTrackerFSMCDBPath; // Path to CDB entry for the Manso FSM tracker component. static const char* fgkDecisionComponentCDBPath; // Path to CDB entry for trigger decision component. + static const char* fgkFieldIntegralsCDBPath; // Path to CDB entry for magnetic field integrals. ClassDef(AliHLTMUONConstants, 0); // Interface class to dHLT constants. }; diff --git a/HLT/MUON/AliHLTMUONMansoTrack.cxx b/HLT/MUON/AliHLTMUONMansoTrack.cxx index e3259fd51b7..0ec164f1d20 100644 --- a/HLT/MUON/AliHLTMUONMansoTrack.cxx +++ b/HLT/MUON/AliHLTMUONMansoTrack.cxx @@ -108,6 +108,11 @@ AliHLTMUONMansoTrack::AliHLTMUONMansoTrack( fHit[1] = hit8; fHit[2] = hit9; fHit[3] = hit10; + for (int i = 0; i < 4; i++) + { + fRoICentre[i] = TVector3(0, 0, 0); + fRoIRadius[i] = -1; + } } @@ -197,6 +202,36 @@ void AliHLTMUONMansoTrack::Print(Option_t* option) const cout << "Used Zmiddle = " << fZmiddle << " cm and QBL = " << fQBL << " T.m for the momentum calculation." << endl; + cout << "Region of interest information:" << endl; + streamsize w = cout.width(); + ios::fmtflags f = cout.flags(); + cout << setw(9) << "Chamber" + << setw(12) << "X (cm)" + << setw(12) << "Y (cm)" + << setw(12) << "Z (cm)" + << setw(12) << "Radius (cm)" << endl; + for (int i = 0; i < 4; i++) + { + cout << setw(9) << i+11; + if (fRoIRadius[i] != -1) + { + cout << setw(12) << fRoICentre[i].X() + << setw(12) << fRoICentre[i].Y() + << setw(12) << fRoICentre[i].Z() + << setw(12) << fRoIRadius[i]; + } + else + { + cout << setw(12) << "-" + << setw(12) << "-" + << setw(12) << "-" + << setw(12) << "-"; + } + cout << endl; + } + cout.width(w); // reset the field width to previous value. + cout.flags(f); // reset the flags to previous values. + for (int i = 0; i < 4; i++) { cout << "===== Hit on chamber: " << i+7 << " =====" << endl; @@ -270,3 +305,60 @@ bool AliHLTMUONMansoTrack::operator == (const AliHLTMUONMansoTrack& track) const and fHit[0] == track.fHit[0] and fHit[1] == track.fHit[1] and fHit[2] == track.fHit[2] and fHit[3] == track.fHit[3]; } + + +void AliHLTMUONMansoTrack::SetDebugData(Float_t zmiddle, Float_t bfieldintegral) +{ + // Sets the extra debugging information. + + fZmiddle = zmiddle; + fQBL = bfieldintegral; +} + + +const TVector3& AliHLTMUONMansoTrack::RoICentre(Int_t chamber) const +{ + // Returns the ragion of interest centre point for a given chamber. + + if (7 <= chamber and chamber <= 10) return fRoICentre[chamber - 7]; + + AliError(Form( + "Chamber number %d is not in the valid range [7..10].", + int(chamber) + )); + static TVector3 zeroVector(0, 0, 0); + return zeroVector; +} + + +Float_t AliHLTMUONMansoTrack::RoIRadius(Int_t chamber) const +{ + // Returns the ragion of interest radius for a given chamber. + + if (7 <= chamber and chamber <= 10) return fRoIRadius[chamber - 7]; + + AliError(Form( + "Chamber number %d is not in the valid range [7..10].", + int(chamber) + )); + return -1; +} + + +void AliHLTMUONMansoTrack::SetRoI(Int_t chamber, Float_t x, Float_t y, Float_t z, Float_t r) +{ + // Returns the ragion of interest radius for a given chamber. + + if (7 <= chamber and chamber <= 10) + { + fRoICentre[chamber - 7] = TVector3(x, y, z); + fRoIRadius[chamber - 7] = r; + } + else + { + AliError(Form( + "Chamber number %d is not in the valid range [7..10].", + int(chamber) + )); + } +} diff --git a/HLT/MUON/AliHLTMUONMansoTrack.h b/HLT/MUON/AliHLTMUONMansoTrack.h index 2877dbb9f2a..7c85e68ad58 100644 --- a/HLT/MUON/AliHLTMUONMansoTrack.h +++ b/HLT/MUON/AliHLTMUONMansoTrack.h @@ -182,6 +182,44 @@ public: * the calculation of the momentum. Value returned in (T.m) tesla metres. */ Float_t QBL() const { return fQBL; } + + /** + * Sets the extra debugging information. + * @param zmiddle The Z coordinate of the middle of the magnetic field + * assumed during momentum calculation. + * @param bfieldintegral The integrated magnetic field strength assumed + * during momentum calculation. + */ + void SetDebugData(Float_t zmiddle, Float_t bfieldintegral); + + /** + * Returns the Region of Interest (RoI) centre point for the given chamber. + * \param chamber Specifies the chamber for which to return the centre point. + * Valid values are in the range [7..10]. + * \return The RoI centre or a zero vector if the RoI is not set or the + * chamber is an incorrect value. + */ + const TVector3& RoICentre(Int_t chamber) const; + + /** + * Returns the Region of Interest (RoI) radius for the given chamber. + * \param chamber Specifies the chamber for which to return the radius. + * Valid values are in the range [7..10]. + * \return The RoI radius or -1 if the RoI is not set or the chamber is + * an incorrect value. + */ + Float_t RoIRadius(Int_t chamber) const; + + /** + * Sets the Region of Interest (RoI) on the given chamber. + * \param chamber Specifies the chamber for which to return the radius. + * Valid values are in the range [7..10]. + * \param x X coordinate of the RoI centre point. + * \param y Y coordinate of the RoI centre point. + * \param z Z coordinate of the RoI centre point. + * \param r radius of the RoI. + */ + void SetRoI(Int_t chamber, Float_t x, Float_t y, Float_t z, Float_t r); private: @@ -195,6 +233,8 @@ private: Float_t fChi2; ///< Chi squared of fit. const AliHLTMUONTriggerRecord* fTrigRec; ///< Corresponding trigger record. const AliHLTMUONRecHit* fHit[4]; ///< Particle hits on tracking chambers 7 to 10. + TVector3 fRoICentre[4]; ///< Region of Interest centre points. + Float_t fRoIRadius[4]; ///< Region of Interest radii. // The following is debugging information and may not be filled if the // dHLT components were not set to produce this information. diff --git a/HLT/MUON/AliHLTMUONProcessor.cxx b/HLT/MUON/AliHLTMUONProcessor.cxx index f3281426de5..6dc71a8d32c 100644 --- a/HLT/MUON/AliHLTMUONProcessor.cxx +++ b/HLT/MUON/AliHLTMUONProcessor.cxx @@ -27,13 +27,18 @@ /// #include "AliHLTMUONProcessor.h" +#include "AliHLTMUONConstants.h" #include "AliMUONRecoParam.h" #include "AliCDBManager.h" #include "AliCDBStorage.h" #include "AliCDBEntry.h" +#include "AliGRPManager.h" +#include "AliGRPObject.h" +#include "AliMagF.h" #include "AliMpCDB.h" #include "AliMpDDLStore.h" #include "AliMpDEStore.h" +#include "TGeoGlobalMagField.h" #include "TMap.h" #include "TObjString.h" #include "TString.h" @@ -577,6 +582,94 @@ int AliHLTMUONProcessor::GetPositiveFloatFromTMap( } +int AliHLTMUONProcessor::FetchFieldIntegral(Double_t& bfieldintegral) const +{ + // Fetches the correct dipole magnetic field integral to use. + + Float_t currentL3 = 0; + Float_t currentDip = 0; + + if (TGeoGlobalMagField::Instance() == NULL or + (TGeoGlobalMagField::Instance() != NULL and TGeoGlobalMagField::Instance()->GetField() == NULL) + ) + { + HLTWarning("The magnetic field has not been set in TGeoGlobalMagField." + " Will try and load the GRP entry directly." + ); + + AliGRPManager grpman; + if (not grpman.ReadGRPEntry() or grpman.GetGRPData() == NULL) + { + HLTError("GRP entry could not be loaded."); + return -EIO; + } + + const AliGRPObject* grp = grpman.GetGRPData(); + Char_t polarityL3 = grp->GetL3Polarity(); + Char_t polarityDip = grp->GetDipolePolarity(); + currentL3 = grp->GetL3Current(AliGRPObject::kMean); + currentDip = grp->GetDipoleCurrent(AliGRPObject::kMean); + if (polarityL3 == AliGRPObject::GetInvalidChar()) + { + HLTError("L3 polarity in GRP is invalid."); + return -EPROTO; + } + if (polarityDip == AliGRPObject::GetInvalidChar()) + { + HLTError("Dipole polarity in GRP is invalid."); + return -EPROTO; + } + if (currentL3 == AliGRPObject::GetInvalidFloat()) + { + HLTError("L3 current in GRP is invalid."); + return -EPROTO; + } + if (currentDip == AliGRPObject::GetInvalidFloat()) + { + HLTError("Dipole current in GRP is invalid."); + return -EPROTO; + } + if (grp->IsPolarityConventionLHC()) + { + currentL3 *= (polarityL3 ? -1:1); + currentDip *= (polarityDip ? -1:1); + } + else + { + currentL3 *= (polarityL3 ? -1:1); + currentDip *= (polarityDip ? 1:-1); + } + } + else + { + TVirtualMagField* vfield = TGeoGlobalMagField::Instance()->GetField(); + AliMagF* field = dynamic_cast(vfield); + if (vfield->IsA() != AliMagF::Class() and field != NULL) + { + HLTError(Form( + "The magnetic field is not of type AliMagF." + " Do not know how to handle class of type '%s'.", + vfield->ClassName() + )); + return -EPROTO; + } + currentL3 = field->GetCurrentSol(); + currentDip = field->GetCurrentDip(); + } + + const char* path = AliHLTMUONConstants::FieldIntegralsCDBPath(); + TMap* map = NULL; + int result = FetchTMapFromCDB(path, map); + if (result != 0) return result; + const char* paramName = Form("L3_current=%0.2e;Dipole_current=%0.2e", currentL3, currentDip); + Double_t value; + result = GetFloatFromTMap(map, paramName, value, path); + if (result != 0) return result; + bfieldintegral = value; + return 0; +} + + int AliHLTMUONProcessor::LoadRecoParamsFromCDB(AliMUONRecoParam*& params) const { /// Fetches the reconstruction parameters object from the CDB for MUON. diff --git a/HLT/MUON/AliHLTMUONProcessor.h b/HLT/MUON/AliHLTMUONProcessor.h index d788f108d35..35710cf1a34 100644 --- a/HLT/MUON/AliHLTMUONProcessor.h +++ b/HLT/MUON/AliHLTMUONProcessor.h @@ -350,6 +350,17 @@ protected: const char* pathToEntry = NULL, const char* prettyName = NULL ) const; + /** + * Loads the appropriate field integral from the CDB based on the currently + * loaded global magnetic field in TGeoGlobalMagField. If the global field is + * not loaded then we try load the GRP entry to figure out the correct integral. + * [out] \param bfieldintegral Will be filled with the dipole magnetic field + * integral value to use. + * \return Zero if the field integral could be found and is valid. Otherwise an + * error code is returned, which is compatible with the HLT framework. + */ + int FetchFieldIntegral(Double_t& bfieldintegral) const; + /** * Fetches the reconstruction parameters object from the CDB for MUON. * [out] \param params This will be filled with the reconstruction diff --git a/HLT/MUON/AliHLTMUONTriggerRecord.cxx b/HLT/MUON/AliHLTMUONTriggerRecord.cxx index 812f83c3977..b096a6f6d7e 100644 --- a/HLT/MUON/AliHLTMUONTriggerRecord.cxx +++ b/HLT/MUON/AliHLTMUONTriggerRecord.cxx @@ -331,12 +331,23 @@ void AliHLTMUONTriggerRecord::Print(Option_t* option) const << setw(12) << "DetElemID" << endl; for (int i = 0; i < 4; i++) { - cout << setw(9) << i+11 - << setw(14) << fHit[i].X() - << setw(12) << fHit[i].Y() - << setw(12) << fHit[i].Z() - << setw(12) << fDetElemId[i] - << endl; + cout << setw(9) << i+11; + if (fDetElemId[i] != -1) + { + cout << setw(14) << fHit[i].X() + << setw(12) << fHit[i].Y() + << setw(12) << fHit[i].Z() + << setw(12) << fDetElemId[i] + << endl; + } + else + { + cout << setw(14) << "-" + << setw(12) << "-" + << setw(12) << "-" + << setw(12) << "-" + << endl; + } } cout << setw(9) << "Chamber" << setw(18+17*2) << "X bit patterns for local boards" diff --git a/HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.cxx b/HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.cxx index c3120abef66..f4d7771cd8e 100644 --- a/HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.cxx +++ b/HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.cxx @@ -306,6 +306,7 @@ int AliHLTMUONRootifierComponent::DoEvent( ); for (int k = 0; k < 4; k++) { + if (not hitset[k]) continue; Int_t detElemId = AliHLTMUONUtils::GetDetElemIdFromFlags(t.fHit[k].fFlags); tr->SetHit(k+11, t.fHit[k].fX, t.fHit[k].fY, t.fHit[k].fZ, detElemId); } @@ -394,15 +395,17 @@ int AliHLTMUONRootifierComponent::DoEvent( 0, 0, 0, 0, 0, sourceDDL ); } - - for (Int_t j = 0; j < 4; ++j) + else { - if (triginfo.fDetElemId[j] != trigrec->DetElemId(j+11)) + for (Int_t j = 0; j < 4; ++j) { - HLTWarning("Found a trigger record with a hit on chamber %d with a different" - " detector element ID %d than the debug information %d.", - j, trigrec->DetElemId(j+11), triginfo.fDetElemId[j] - ); + if (trigrec->DetElemId(j+11) != -1 and triginfo.fDetElemId[j] != trigrec->DetElemId(j+11)) + { + HLTWarning("Found a trigger record with a hit on chamber %d with a different" + " detector element ID %d than the debug information %d.", + j, trigrec->DetElemId(j+11), triginfo.fDetElemId[j] + ); + } } } @@ -617,6 +620,8 @@ int AliHLTMUONRootifierComponent::DoEvent( } } + std::map trackMap; + // Now we can look for tracks to add. We needed the ROOT trigger records // and reco hits created before we can create track objects. for (block = GetFirstInputBlock(AliHLTMUONConstants::MansoTracksBlockDataType()); @@ -635,93 +640,40 @@ int AliHLTMUONRootifierComponent::DoEvent( for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++) { const AliHLTMUONMansoTrackStruct& t = inblock[n]; - - AliHLTMUONParticleSign sign; - bool hitset[4]; - AliHLTMUONUtils::UnpackMansoTrackFlags( - t.fFlags, sign, hitset - ); - - // Try find the trigger record in 'event'. - const AliHLTMUONTriggerRecord* trigrec = NULL; - for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++) - { - if (event.Array()[k]->IsA() != AliHLTMUONTriggerRecord::Class()) - continue; - const AliHLTMUONTriggerRecord* tk = - static_cast(event.Array()[k]); - if (tk->Id() == t.fTrigRec) - { - trigrec = tk; - break; - } - } - - // Now try find the hits in 'event'. - // If they cannot be found then create new ones. - const AliHLTMUONRecHit* hit7 = NULL; - const AliHLTMUONRecHit* hit8 = NULL; - const AliHLTMUONRecHit* hit9 = NULL; - const AliHLTMUONRecHit* hit10 = NULL; - for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++) - { - if (event.Array()[k]->IsA() != AliHLTMUONRecHit::Class()) - continue; - const AliHLTMUONRecHit* h = - static_cast(event.Array()[k]); - - if (hitset[0] and h->X() == t.fHit[0].fX and h->Y() == t.fHit[0].fY - and h->Z() == t.fHit[0].fZ) - { - hit7 = h; - } - if (hitset[1] and h->X() == t.fHit[1].fX and h->Y() == t.fHit[1].fY - and h->Z() == t.fHit[1].fZ) - { - hit8 = h; - } - if (hitset[2] and h->X() == t.fHit[2].fX and h->Y() == t.fHit[2].fY - and h->Z() == t.fHit[2].fZ) - { - hit9 = h; - } - if (hitset[3] and h->X() == t.fHit[3].fX and h->Y() == t.fHit[3].fY - and h->Z() == t.fHit[3].fZ) - { - hit10 = h; - } - } - AliHLTMUONRecHit* newhit; - if (hitset[0] and hit7 == NULL) - { - newhit = new AliHLTMUONRecHit(t.fHit[0].fX, t.fHit[0].fY, t.fHit[0].fZ); - event.Add(newhit); - hit7 = newhit; - } - if (hitset[1] and hit8 == NULL) - { - newhit = new AliHLTMUONRecHit(t.fHit[1].fX, t.fHit[1].fY, t.fHit[1].fZ); - event.Add(newhit); - hit8 = newhit; - } - if (hitset[2] and hit9 == NULL) + trackMap[t.fId] = AddTrack(event, t); + } + } + + // Look for Manso track candidates to add the debug info to the tracks. + for (block = GetFirstInputBlock(AliHLTMUONConstants::MansoCandidatesBlockDataType()); + block != NULL; + block = GetNextInputBlock() + ) + { + specification |= block->fSpecification; + AliHLTMUONMansoCandidatesBlockReader inblock(block->fPtr, block->fSize); + if (not BlockStructureOk(inblock)) + { + if (DumpDataOnError()) DumpEvent(evtData, trigData); + continue; + } + + for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++) + { + const AliHLTMUONMansoCandidateStruct& tc = inblock[n]; + AliHLTMUONMansoTrack* mtrack = trackMap[tc.fTrack.fId]; + if (mtrack == NULL) { - newhit = new AliHLTMUONRecHit(t.fHit[2].fX, t.fHit[2].fY, t.fHit[2].fZ); - event.Add(newhit); - hit9 = newhit; + // If we got here then we could not find the corresponding Manso + // track. So we need to create and add a new track object. + mtrack = AddTrack(event, tc.fTrack); } - if (hitset[3] and hit10 == NULL) + mtrack->SetDebugData(tc.fZmiddle, tc.fBl); + for (AliHLTUInt32_t i = 0; i < 4; ++i) { - newhit = new AliHLTMUONRecHit(t.fHit[3].fX, t.fHit[3].fY, t.fHit[3].fZ); - event.Add(newhit); - hit10 = newhit; + if (tc.fRoI[i] == AliHLTMUONConstants::NilMansoRoIStruct()) continue; + mtrack->SetRoI(i+7, tc.fRoI[i].fX, tc.fRoI[i].fY, tc.fRoI[i].fZ, tc.fRoI[i].fRadius); } - - AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack( - t.fId, sign, t.fPx, t.fPy, t.fPz, t.fChi2, - trigrec, hit7, hit8, hit9, hit10 - ); - event.Add(tr); } } @@ -897,3 +849,98 @@ int AliHLTMUONRootifierComponent::DoEvent( return 0; } + +AliHLTMUONMansoTrack* AliHLTMUONRootifierComponent::AddTrack( + AliHLTMUONEvent& event, const AliHLTMUONMansoTrackStruct& track + ) +{ + // Converts the track structure and adds it to the event object. + + AliHLTMUONParticleSign sign; + bool hitset[4]; + AliHLTMUONUtils::UnpackMansoTrackFlags( + track.fFlags, sign, hitset + ); + + // Try find the trigger record in 'event'. + const AliHLTMUONTriggerRecord* trigrec = NULL; + for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++) + { + if (event.Array()[k]->IsA() != AliHLTMUONTriggerRecord::Class()) + continue; + const AliHLTMUONTriggerRecord* tk = + static_cast(event.Array()[k]); + if (tk->Id() == track.fTrigRec) + { + trigrec = tk; + break; + } + } + + // Now try find the hits in 'event'. + // If they cannot be found then create new ones. + const AliHLTMUONRecHit* hit7 = NULL; + const AliHLTMUONRecHit* hit8 = NULL; + const AliHLTMUONRecHit* hit9 = NULL; + const AliHLTMUONRecHit* hit10 = NULL; + for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++) + { + if (event.Array()[k]->IsA() != AliHLTMUONRecHit::Class()) + continue; + const AliHLTMUONRecHit* h = + static_cast(event.Array()[k]); + + if (hitset[0] and h->X() == track.fHit[0].fX and h->Y() == track.fHit[0].fY + and h->Z() == track.fHit[0].fZ) + { + hit7 = h; + } + if (hitset[1] and h->X() == track.fHit[1].fX and h->Y() == track.fHit[1].fY + and h->Z() == track.fHit[1].fZ) + { + hit8 = h; + } + if (hitset[2] and h->X() == track.fHit[2].fX and h->Y() == track.fHit[2].fY + and h->Z() == track.fHit[2].fZ) + { + hit9 = h; + } + if (hitset[3] and h->X() == track.fHit[3].fX and h->Y() == track.fHit[3].fY + and h->Z() == track.fHit[3].fZ) + { + hit10 = h; + } + } + AliHLTMUONRecHit* newhit; + if (hitset[0] and hit7 == NULL) + { + newhit = new AliHLTMUONRecHit(track.fHit[0].fX, track.fHit[0].fY, track.fHit[0].fZ); + event.Add(newhit); + hit7 = newhit; + } + if (hitset[1] and hit8 == NULL) + { + newhit = new AliHLTMUONRecHit(track.fHit[1].fX, track.fHit[1].fY, track.fHit[1].fZ); + event.Add(newhit); + hit8 = newhit; + } + if (hitset[2] and hit9 == NULL) + { + newhit = new AliHLTMUONRecHit(track.fHit[2].fX, track.fHit[2].fY, track.fHit[2].fZ); + event.Add(newhit); + hit9 = newhit; + } + if (hitset[3] and hit10 == NULL) + { + newhit = new AliHLTMUONRecHit(track.fHit[3].fX, track.fHit[3].fY, track.fHit[3].fZ); + event.Add(newhit); + hit10 = newhit; + } + + AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack( + track.fId, sign, track.fPx, track.fPy, track.fPz, track.fChi2, + trigrec, hit7, hit8, hit9, hit10 + ); + event.Add(tr); + return tr; +} diff --git a/HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.h b/HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.h index 32698514380..6fc0cd47330 100644 --- a/HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.h +++ b/HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.h @@ -15,6 +15,10 @@ #include "AliHLTMUONProcessor.h" +class AliHLTMUONEvent; +class AliHLTMUONMansoTrack; +extern "C" struct AliHLTMUONMansoTrackStruct; + /** * \class AliHLTMUONRootifierComponent * \brief Converts dHLT raw data blocks into ROOT objects. @@ -93,6 +97,14 @@ private: AliHLTMUONRootifierComponent(const AliHLTMUONRootifierComponent& /*object*/); AliHLTMUONRootifierComponent& operator = (const AliHLTMUONRootifierComponent& /*object*/); + /** + * This method creates a AliHLTMUONMansoTrack object from the track structure + * and adds it to the dHLT event object. + * \param event The dHLT event object. + * \param track The track structure to convert and add to the event. + */ + AliHLTMUONMansoTrack* AddTrack(AliHLTMUONEvent& event, const AliHLTMUONMansoTrackStruct& track); + bool fWarnForUnexpecedBlock; /// Flag indicating if we should log a warning if we got a block of an unexpected type. ClassDef(AliHLTMUONRootifierComponent, 0); // Converter component of dHLT raw data. diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.cxx b/HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.cxx index 96e698c5a8f..cfe16138744 100644 --- a/HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.cxx +++ b/HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.cxx @@ -210,6 +210,30 @@ bool AliHLTMUONCalculations::FitLineToTriggerRecord( /// \param hitset Flags indicating which hits were set in the trigger record. /// \return true if the line could be fitted or false otherwise. + bool lineOk = FitLine(trigger, hitset); + if (lineOk) + { + // Calculate ideal points on chambers 11 and 13: + fgIdealX1 = fgMzx * fgIdealZ1 + fgCzx; + fgIdealY1 = fgMzy * fgIdealZ1 + fgCzy; + fgIdealX2 = fgMzx * fgIdealZ2 + fgCzx; + fgIdealY2 = fgMzy * fgIdealZ2 + fgCzy; + } + return lineOk; +} + + +bool AliHLTMUONCalculations::FitLine( + const AliHLTMUONTriggerRecordStruct& trigger, + const bool hitset[4] + ) +{ + /// Performs a straight line fit to the trigger record hits which are indicated + /// by the hitset flags array. + /// \param trigger The trigger record structure to which we fit a line. + /// \param hitset Flags indicating which hits to use and were set in the trigger record. + /// \return true if the line could be fitted or false otherwise. + AliHLTFloat32_t sumX = 0; AliHLTFloat32_t sumY = 0; AliHLTFloat32_t sumZ = 0; @@ -249,12 +273,6 @@ bool AliHLTMUONCalculations::FitLineToTriggerRecord( fgCzx = meanX - fgMzx * meanZ; fgCzy = meanY - fgMzy * meanZ; - // Calculate ideal points on chambers 11 and 13: - fgIdealX1 = fgMzx * fgIdealZ1 + fgCzx; - fgIdealY1 = fgMzy * fgIdealZ1 + fgCzy; - fgIdealX2 = fgMzx * fgIdealZ2 + fgCzx; - fgIdealY2 = fgMzy * fgIdealZ2 + fgCzy; - return true; } @@ -366,7 +384,7 @@ AliHLTFloat32_t AliHLTMUONCalculations::AliHLTMUONCalculations::ComputeChi2( { /// Calculates the chi squared value for the set of data points given /// the fitted slope and coefficient parameters previously fitted by - /// LineFit(x, y, z, n); + /// one of FitLine(x, y, z, n) or FitLineToTriggerRecord /// The fgSigmaX2 and fgSigmaY2 are used as the variance for the X and /// Y coordinates respectively. Note we assume that the covariance terms /// are zero. @@ -385,3 +403,29 @@ AliHLTFloat32_t AliHLTMUONCalculations::AliHLTMUONCalculations::ComputeChi2( } return chi2; } + + +AliHLTFloat32_t AliHLTMUONCalculations::AliHLTMUONCalculations::ComputeChi2( + const AliHLTMUONTriggerRecordStruct& trigger, + const bool hitset[4] + ) +{ + /// Calculates the chi squared value for trigger record using the hits + /// indicated by the hitset array. + /// \param trigger The trigger record structure for which we compute the chi squared value. + /// \param hitset Flags indicating which hits to use and were set in the trigger record. + /// \return The chi squared value or -1 if it could not be calculated. + + if (not FitLine(trigger, hitset)) return -1; + AliHLTFloat32_t chi2 = 0; + for (AliHLTUInt32_t i = 0; i < 4; i++) + { + if (hitset[i]) + { + AliHLTFloat32_t residualX = fgMzx * trigger.fHit[i].fZ + fgCzx - trigger.fHit[i].fX; + AliHLTFloat32_t residualY = fgMzy * trigger.fHit[i].fZ + fgCzy - trigger.fHit[i].fY; + chi2 += residualX*residualX/fgSigmaX2 + residualY*residualY/fgSigmaY2; + } + } + return chi2; +} diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.h b/HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.h index 9f77b170b51..8208122b682 100644 --- a/HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.h +++ b/HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.h @@ -61,6 +61,11 @@ public: const bool hitset[4] ); + static bool FitLine( + const AliHLTMUONTriggerRecordStruct& trigger, + const bool hitset[4] + ); + static AliHLTFloat32_t IdealZ1() { return fgIdealZ1; } static void IdealZ1(AliHLTFloat32_t value) { fgIdealZ1 = value; } static AliHLTFloat32_t IdealZ2() { return fgIdealZ2; } @@ -91,6 +96,11 @@ public: const AliHLTFloat32_t* z, AliHLTUInt32_t n ); + static AliHLTFloat32_t ComputeChi2( + const AliHLTMUONTriggerRecordStruct& trigger, + const bool hitset[4] + ); + static AliHLTFloat32_t SigmaX2() { return fgSigmaX2; } static void SigmaX2(AliHLTFloat32_t value) { fgSigmaX2 = (value != 0 ? value : 1.); } static AliHLTFloat32_t SigmaY2() { return fgSigmaY2; } diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.cxx b/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.cxx index 7c387a1fb86..be4b35b6e88 100644 --- a/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.cxx +++ b/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.cxx @@ -1,5 +1,5 @@ /************************************************************************** - * This file is property of and copyright by the ALICE HLT Project * + * This file is property of and copyright by the ALICE HLT Project * * All rights reserved. * * * * Primary Authors: * @@ -10,7 +10,7 @@ * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * + * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ @@ -30,6 +30,9 @@ #include "AliHLTMUONCalculations.h" #include "AliHLTMUONConstants.h" #include "AliHLTMUONUtils.h" +#include "AliHLTMUONTriggerRecordsBlockStruct.h" +#include "AliHLTMUONMansoTracksBlockStruct.h" +#include "AliHLTMUONMansoCandidatesBlockStruct.h" #include @@ -209,6 +212,7 @@ AliHLTMUONRecHitStruct AliHLTMUONMansoTrackerFSM::AliLine::FindIntersectWithXYPl AliHLTMUONMansoTrackerFSM::AliHLTMUONMansoTrackerFSM() : + AliHLTLogging(), fCallback(NULL), fSm4state(kSM4Idle), fSm5state(kSM5Idle), @@ -221,12 +225,24 @@ AliHLTMUONMansoTrackerFSM::AliHLTMUONMansoTrackerFSM() : fSt5rec(), fFoundPoint(), fTriggerId(-1), - fTrackId(0) + fTrackId(0), + fMakeCandidates(false), + fCandidatesCount(0), + fCandidatesSize(0), + fCandidates(NULL) { // Default constructor } +AliHLTMUONMansoTrackerFSM::~AliHLTMUONMansoTrackerFSM() +{ + // Default destructor cleans up any allocated memory. + + if (fCandidates != NULL) delete [] fCandidates; +} + + void AliHLTMUONMansoTrackerFSM::FindTrack(const AliHLTMUONTriggerRecordStruct& trigger) { // Tries to find the track from the trigger seed. @@ -274,6 +290,24 @@ void AliHLTMUONMansoTrackerFSM::FindTrack(const AliHLTMUONTriggerRecordStruct& t // that method could call one of our methods again, so we need to be // in a consistant internal state. fSm5state = kWaitChamber10; + + if (fMakeCandidates) + { + fMc1.fCandidate = AddTrackCandidate(); + if (fMc1.fCandidate != NULL) + { + *fMc1.fCandidate = AliHLTMUONConstants::NilMansoCandidateStruct(); + fMc1.fCandidate->fTrack.fId = -1; + fMc1.fCandidate->fTrack.fTrigRec = fTriggerId; + fMc1.fCandidate->fTrack.fChi2 = -1; + fMc1.fCandidate->fZmiddle = AliHLTMUONCalculations::Zf(); + fMc1.fCandidate->fBl = AliHLTMUONCalculations::QBL(); + fMc1.fCandidate->fRoI[3].fX = fMc1.fRoi.Centre().fX; + fMc1.fCandidate->fRoI[3].fY = fMc1.fRoi.Centre().fY; + fMc1.fCandidate->fRoI[3].fZ = fMc1.fRoi.Centre().fZ; + fMc1.fCandidate->fRoI[3].fRadius = fMc1.fRoi.Radius(); + } + } AliHLTFloat32_t left, right, bottom, top; fMc1.fRoi.GetBoundaryBox(left, right, bottom, top); @@ -404,6 +438,16 @@ bool AliHLTMUONMansoTrackerFSM::FillTrackData(AliHLTMUONMansoTrackStruct& track) track.fFlags = AliHLTMUONUtils::PackMansoTrackFlags( AliHLTMUONCalculations::Sign(), hitset ); + + if (fMakeCandidates) + { + AliHLTMUONMansoCandidateStruct* candidate = fSt5rec->fTag.fCandidate; + if (candidate != NULL) + { + candidate->fTrack = track; + } + } + return calculated; } @@ -441,8 +485,8 @@ void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7( switch (fSm4state) { case kWaitChamber7: - fSm4state = kWaitMoreChamber7; - + // We switch state below. + case kWaitMoreChamber7: for (AliHLTUInt32_t j = 0; j < count; j++) { @@ -450,6 +494,9 @@ void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber7( // Check that the cluster actually is in our region of interest on station 4. if ( data->fRoi.Contains(cluster) ) { + // Go to next wait state only if we actually found anything in the RoI. + fSm4state = kWaitMoreChamber7; + DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 7."); AliStation4Data* newdata = fSt4points.Add(); newdata->fClusterPoint = cluster; @@ -474,9 +521,8 @@ void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8( switch (fSm4state) { case kWaitChamber8: - fSm4state = kWaitMoreChamber8; fSt4chamber = kChamber8; - + case kWaitMoreChamber8: for (AliHLTUInt32_t j = 0; j < count; j++) { @@ -484,6 +530,9 @@ void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber8( // Check that the cluster actually is in our region of interest on station 4. if ( data->fRoi.Contains(cluster) ) { + // Go to next wait state only if we actually found anything in the RoI. + fSm4state = kWaitMoreChamber8; + DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 8."); AliStation4Data* newdata = fSt4points.Add(); newdata->fClusterPoint = cluster; @@ -507,9 +556,8 @@ void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9( switch (fSm5state) { case kWaitChamber9: - fSm5state = kWaitMoreChamber9; fSm4state = kWaitChamber8; // Start SM4. - + case kWaitMoreChamber9: for (AliHLTUInt32_t j = 0; j < count; j++) { @@ -517,10 +565,13 @@ void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber9( // Check that the cluster actually is in our region of interest on station 5. if ( fMc1.fRoi.Contains(cluster) ) { + // Go to next wait state only if we actually found anything in the RoI. + fSm5state = kWaitMoreChamber9; + DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 9."); AliStation5Data* data = fSt5data.Add(); data->fClusterPoint = cluster; - ProjectToStation4(data, fgZ9); // This adds a new request for station 4. + ProjectToStation4(data, fgZ9, 2); // This adds a new request for station 4. } } break; @@ -540,7 +591,6 @@ void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10( switch (fSm5state) { case kWaitChamber10: - fSm5state = kWaitMoreChamber10; fSm4state = kWaitChamber8; // Start SM4. case kWaitMoreChamber10: @@ -550,10 +600,13 @@ void AliHLTMUONMansoTrackerFSM::ReceiveClustersChamber10( // Check that the cluster actually is in our region of interest on station 5. if ( fMc1.fRoi.Contains(cluster) ) { + // Go to next wait state only if we actually found anything in the RoI. + fSm5state = kWaitMoreChamber10; + DebugTrace("Adding cluster [" << cluster.fX << ", " << cluster.fY << "] from chamber 10."); AliStation5Data* data = fSt5data.Add(); data->fClusterPoint = cluster; - ProjectToStation4(data, fgZ10); // This adds a new request for station 4. + ProjectToStation4(data, fgZ10, 3); // This adds a new request for station 4. } } break; @@ -620,6 +673,7 @@ void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8() AliStation5Data* data = fSt5data.Add(); data->fClusterPoint = rec->fClusterPoint; data->fTag.fLine = rec->fTag.fLine; + data->fTag.fCandidate = rec->fTag.fCandidate; // Rebuild a region of interest for chamber 7. // Remember the parameters a and b are station specific. @@ -627,6 +681,14 @@ void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber8() data->fTag.fChamber = kChamber7; data->fTag.fRoi.Create(p7, fgA7, fgB7); + if (fMakeCandidates and data->fTag.fCandidate != NULL) + { + data->fTag.fCandidate->fRoI[0].fX = data->fTag.fRoi.Centre().fX; + data->fTag.fCandidate->fRoI[0].fY = data->fTag.fRoi.Centre().fY; + data->fTag.fCandidate->fRoI[0].fZ = data->fTag.fRoi.Centre().fZ; + data->fTag.fCandidate->fRoI[0].fRadius = data->fTag.fRoi.Radius(); + } + AliHLTFloat32_t left, right, bottom, top; data->fTag.fRoi.GetBoundaryBox(left, right, bottom, top); // Make request for chamber 7 data. @@ -684,12 +746,20 @@ void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10() // No clusters found on chamber 10 so we need to make a request for // clusters from chamber 9: AliHLTMUONRecHitStruct p9 = fMc1.fLine.FindIntersectWithXYPlain( fgZ9 ); - + // Build a region of interest for tracking station 5 (chamber 9). // Remember the parameters a and b are station specific. fMc1.fChamber = kChamber9; fMc1.fRoi.Create(p9, fgA9, fgB9); - + + if (fMakeCandidates and fMc1.fCandidate != NULL) + { + fMc1.fCandidate->fRoI[2].fX = fMc1.fRoi.Centre().fX; + fMc1.fCandidate->fRoI[2].fY = fMc1.fRoi.Centre().fY; + fMc1.fCandidate->fRoI[2].fZ = fMc1.fRoi.Centre().fZ; + fMc1.fCandidate->fRoI[2].fRadius = fMc1.fRoi.Radius(); + } + AliHLTFloat32_t left, right, bottom, top; fMc1.fRoi.GetBoundaryBox(left, right, bottom, top); RequestClusters(left, right, bottom, top, kChamber9, &fMc1); @@ -710,7 +780,7 @@ void AliHLTMUONMansoTrackerFSM::EndOfClustersChamber10() void AliHLTMUONMansoTrackerFSM::ProjectToStation4( - AliStation5Data* data, register AliHLTFloat32_t station5z + AliStation5Data* data, AliHLTFloat32_t station5z, AliHLTUInt32_t chamberSt5 ) { // Perform chamber specific operations: @@ -722,7 +792,9 @@ void AliHLTMUONMansoTrackerFSM::ProjectToStation4( || fSm4state == kWaitChamber7 || fSm4state == kWaitMoreChamber7 ); + assert( chamberSt5 == 2 or chamberSt5 == 3 ); AliTagData* tag = &data->fTag; + int chamber = 0; if (fSm4state == kWaitChamber8 || fSm4state == kWaitMoreChamber8) { // Form the vector line between trigger station 1 and tracking station 5, @@ -734,6 +806,7 @@ void AliHLTMUONMansoTrackerFSM::ProjectToStation4( // Build a region of interest for tracking station 4. tag->fChamber = kChamber8; tag->fRoi.Create(intercept, fgA8, fgB8); + chamber = 1; } else { @@ -746,6 +819,33 @@ void AliHLTMUONMansoTrackerFSM::ProjectToStation4( // Build a region of interest for tracking station 4. tag->fChamber = kChamber7; tag->fRoi.Create(intercept, fgA7, fgB7); + chamber = 0; + } + + if (fMakeCandidates) + { + // Make a copy of the track candidate if the exisiting track candidate + // has already had its point on the given chamber filled. + if (fMc1.fCandidate != NULL and + fMc1.fCandidate->fTrack.fHit[chamberSt5] == AliHLTMUONConstants::NilRecHitStruct() + ) + { + tag->fCandidate = fMc1.fCandidate; + } + else + { + tag->fCandidate = AddTrackCandidate(); + if (tag->fCandidate != NULL) *tag->fCandidate = *fMc1.fCandidate; + } + // Now fill the cluster point found on station 5 and RoI on station 4. + if (tag->fCandidate != NULL) + { + tag->fCandidate->fTrack.fHit[chamberSt5] = data->fClusterPoint; + tag->fCandidate->fRoI[chamber].fX = tag->fRoi.Centre().fX; + tag->fCandidate->fRoI[chamber].fY = tag->fRoi.Centre().fY; + tag->fCandidate->fRoI[chamber].fZ = tag->fRoi.Centre().fZ; + tag->fCandidate->fRoI[chamber].fRadius = tag->fRoi.Radius(); + } } // Make the request for clusters from station 4. @@ -806,3 +906,43 @@ void AliHLTMUONMansoTrackerFSM::ProcessClusters() NoTrackFound(); } + +AliHLTMUONMansoCandidateStruct* AliHLTMUONMansoTrackerFSM::AddTrackCandidate() +{ + // Adds a new track candidate to the fCandidates list and returns a pointer + // to the new structure. + + // First allocate or reallocate buffer if necessary. + if (fCandidates == NULL) + { + try + { + fCandidates = new AliHLTMUONMansoCandidateStruct[1024]; + } + catch (...) + { + HLTError("Could not allocate buffer space for Manso track candidates."); + return NULL; + } + fCandidatesSize = 1024; + } + else if (fCandidatesCount >= fCandidatesSize) + { + AliHLTMUONMansoCandidateStruct* newbuf = NULL; + try + { + newbuf = new AliHLTMUONMansoCandidateStruct[fCandidatesSize*2]; + } + catch (...) + { + HLTError("Could not allocate more buffer space for Manso track candidates."); + return NULL; + } + for (AliHLTUInt32_t i = 0; i < fCandidatesSize; ++i) newbuf[i] = fCandidates[i]; + delete [] fCandidates; + fCandidates = newbuf; + fCandidatesSize = fCandidatesSize*2; + } + + return &fCandidates[fCandidatesCount++]; +} diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.h b/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.h index 4a9c18402f9..a8ca52d475f 100644 --- a/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.h +++ b/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.h @@ -1,7 +1,7 @@ #ifndef ALIHLTMUONMANSOTRACKERFSM_H #define ALIHLTMUONMANSOTRACKERFSM_H /************************************************************************** - * This file is property of and copyright by the ALICE HLT Project * + * This file is property of and copyright by the ALICE HLT Project * * All rights reserved. * * * * Primary Authors: * @@ -12,7 +12,7 @@ * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * + * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ @@ -25,26 +25,29 @@ /// @brief Declaration of the AliHLTMUONMansoTrackerFSM class which implements the Manso tracking algorithm. /// +#include "AliHLTLogging.h" #include "AliHLTMUONDataTypes.h" #include "AliHLTMUONList.h" #include "AliHLTMUONCountedList.h" #include "AliHLTMUONRecHitsBlockStruct.h" -#include "AliHLTMUONTriggerRecordsBlockStruct.h" -#include "AliHLTMUONMansoTracksBlockStruct.h" #include "AliHLTMUONMansoTrackerFSMCallback.h" #include +extern "C" struct AliHLTMUONTriggerRecordStruct; +extern "C" struct AliHLTMUONMansoTrackStruct; +extern "C" struct AliHLTMUONMansoCandidateStruct; + /** * The AliHLTMUONMansoTrackerFSM implements the Manso tracking * algorithm as a finite state machine, which partially reconstructs * tracks in the muon spectrometer. */ -class AliHLTMUONMansoTrackerFSM +class AliHLTMUONMansoTrackerFSM : public AliHLTLogging { public: AliHLTMUONMansoTrackerFSM(); - virtual ~AliHLTMUONMansoTrackerFSM() {} + virtual ~AliHLTMUONMansoTrackerFSM(); /* This is the starting point for the tracking algorithm. The tracker is @@ -96,7 +99,21 @@ public: { fCallback = callback; }; - + + /// Returns the flag indicating if track candidates are stored. + bool MakeCandidates() const { return fMakeCandidates; } + + /// Sets the flag to indicate if track candidates are stored or not. + void MakeCandidates(bool value) { fMakeCandidates = value; } + + /// Returns the number of track candidates found in the list returned by TrackCandidates(). + AliHLTUInt32_t TrackCandidatesCount() const { return fCandidatesCount; } + + /// Returns the array of track candidates. + const AliHLTMUONMansoCandidateStruct* TrackCandidates() const { return fCandidates; } + + /// Removes all the elements in the track candidates array. + void ZeroTrackCandidatesList() { fCandidatesCount = 0; } /* Get and set methods for the a and b parameters used to build the region of interests. Refer to AliRegionOfInterest for details about a and b parameters. @@ -165,6 +182,12 @@ protected: bool Contains(AliHLTMUONRecHitStruct p) const; void GetBoundaryBox(AliHLTFloat32_t& left, AliHLTFloat32_t& right, AliHLTFloat32_t& bottom, AliHLTFloat32_t& top) const; + + /// Returns the centre point of the region of interest. + const AliHLTMUONRecHitStruct& Centre() const { return fCentre; } + + /// Returns the radius of the region of interest disk. + AliHLTFloat32_t Radius() const { return fRs; } private: @@ -237,11 +260,12 @@ protected: class AliTagData { public: - AliTagData() : fChamber(kChamber1), fRoi(), fLine() {}; + AliTagData() : fChamber(kChamber1), fRoi(), fLine(), fCandidate(NULL) {}; AliHLTMUONChamberName fChamber; // The chamber on which the region of interest lies. AliRegionOfInterest fRoi; // Region of interest on the next station. AliLine fLine; // line between a cluster point and the previous station. + AliHLTMUONMansoCandidateStruct* fCandidate; // Track candidate related to the RoI. }; class AliStation5Data @@ -287,7 +311,7 @@ protected: void EndOfClustersChamber9(); void EndOfClustersChamber10(); - void ProjectToStation4(AliStation5Data* data, register AliHLTFloat32_t station5z); + void ProjectToStation4(AliStation5Data* data, AliHLTFloat32_t station5z, AliHLTUInt32_t chamberSt5); void ProcessClusters(); #ifdef DEBUG @@ -335,6 +359,10 @@ protected: AliHLTInt32_t fTriggerId; // The current ID number of the trigger record being processed. AliHLTInt32_t fTrackId; // Track ID counter for the current track. + bool fMakeCandidates; // Indicates if the track candidates should be recorded. + AliHLTUInt32_t fCandidatesCount; // The number of track candidates in the fCandidates list. + AliHLTUInt32_t fCandidatesSize; // Number of elements that the fCandidates list can store. + AliHLTMUONMansoCandidateStruct* fCandidates; // The track candidates buffer. /* To request clusters from the boundary box specified by the 'left', 'right', 'top' and 'bottom' boundaries and on the given chamber use this method call. @@ -382,6 +410,13 @@ protected: assert( fCallback != NULL ); fCallback->NoTrackFound(this); }; + + /** + * Adds a new track candidate to the fCandidates list and returns the pointer + * to the new structure to be filled. + * \returns a pointer to the new structure and NULL if we ran out of space. + */ + AliHLTMUONMansoCandidateStruct* AddTrackCandidate(); private: diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx b/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx index 380df05ff1c..01655d6963c 100644 --- a/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx +++ b/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx @@ -1,5 +1,5 @@ /************************************************************************** - * This file is property of and copyright by the ALICE HLT Project * + * This file is property of and copyright by the ALICE HLT Project * * All rights reserved. * * * * Primary Authors: * @@ -11,7 +11,7 @@ * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * + * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ @@ -167,6 +167,7 @@ int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv) FreeMemory(); fWarnForUnexpecedBlock = false; + bool makeCandidates = false; ResetCanLoadFlags(); double zmiddle = 0; double bfieldintegral = 0; @@ -377,7 +378,13 @@ int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv) fWarnForUnexpecedBlock = true; continue; } - + + if (strcmp(argv[i], "-makecandidates") == 0) + { + makeCandidates = true; + continue; + } + HLTError("Unknown option '%s'.", argv[i]); return -EINVAL; } @@ -392,6 +399,7 @@ int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv) return -ENOMEM; } fTracker->SetCallback(this); + fTracker->MakeCandidates(makeCandidates); // Set all the parameters that were found on the command line. if (not fCanLoadZmiddle) AliHLTMUONCalculations::Zf(zmiddle); @@ -552,9 +560,20 @@ int AliHLTMUONMansoTrackerFSMComponent::ReadConfigFromCDB() if (fCanLoadBL) { - result = GetFloatFromTMap(map, "bfieldintegral", value, pathToEntry, "integrated magnetic field"); - if (result != 0) return result; - AliHLTMUONCalculations::QBL(value); + Double_t bfieldintegral; + result = FetchFieldIntegral(bfieldintegral); + if (result == 0) + { + AliHLTMUONCalculations::QBL(bfieldintegral); + } + else + { + HLTWarning("Failed to load the magnetic field integral from GRP information."); + result = GetFloatFromTMap(map, "bfieldintegral", value, pathToEntry, "integrated magnetic field"); + if (result != 0) return result; + HLTWarning(Form("Using deprecated magnetic field integral value of %f T.m.", value)); + AliHLTMUONCalculations::QBL(value); + } } if (fCanLoadA[0]) @@ -855,8 +874,43 @@ int AliHLTMUONMansoTrackerFSMComponent::DoEvent( bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType(); bd.fSpecification = specification; outputBlocks.push_back(bd); - size = block.BytesUsed(); - + AliHLTUInt32_t totalSize = block.BytesUsed(); + + if (fTracker->MakeCandidates()) + { + AliHLTMUONMansoCandidatesBlockWriter candidatesBlock(outputPtr+totalSize, size-totalSize); + if (not candidatesBlock.InitCommonHeader()) + { + HLTError("Buffer overflowed. There are only %d bytes left in the buffer," + " but we need a minimum of %d bytes.", + size, sizeof(AliHLTMUONMansoCandidatesBlockWriter::HeaderType) + ); + if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks); + size = 0; // Important to tell framework that nothing was generated. + return -ENOBUFS; + } + + // Fill in the output block buffer. + candidatesBlock.SetNumberOfEntries(fTracker->TrackCandidatesCount()); + for (AliHLTUInt32_t i = 0; i < fTracker->TrackCandidatesCount(); ++i) + { + candidatesBlock[i] = fTracker->TrackCandidates()[i]; + } + + fTracker->ZeroTrackCandidatesList(); + + AliHLTComponentBlockData bdc; + FillBlockData(bdc); + bdc.fPtr = outputPtr; + bdc.fOffset = totalSize; + bdc.fSize = candidatesBlock.BytesUsed(); + bdc.fDataType = AliHLTMUONConstants::MansoCandidatesBlockDataType(); + bdc.fSpecification = specification; + outputBlocks.push_back(bdc); + totalSize += candidatesBlock.BytesUsed(); + } + + size = totalSize; return 0; } diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.h b/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.h index fed3f5f9577..b63415c18cf 100644 --- a/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.h +++ b/HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.h @@ -1,7 +1,7 @@ #ifndef AliHLTMUONMANSOTRACKERFSMCOMPONENT_H #define AliHLTMUONMANSOTRACKERFSMCOMPONENT_H /************************************************************************** - * This file is property of and copyright by the ALICE HLT Project * + * This file is property of and copyright by the ALICE HLT Project * * All rights reserved. * * * * Primary Authors: * @@ -13,7 +13,7 @@ * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * + * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ @@ -132,6 +132,9 @@ struct AliHLTMUONRecHitStruct; * \li -dumppath path
* Allows one to specify the path in which to dump the received data blocks * if an error occurs.
+ * \li -makecandidates
+ * Indicates if the Manso track candidates data block should be generated. + * This kind of information is useful for debugging.
* *

Standard configuration:

* This component should normally be configured with no extra options. diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructor.cxx b/HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructor.cxx index a1114b58a66..64bae02d3f3 100644 --- a/HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructor.cxx +++ b/HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructor.cxx @@ -46,6 +46,7 @@ #include "AliHLTMUONUtils.h" #include "AliHLTMUONConstants.h" #include "AliHLTMUONCalculations.h" +#include "AliMUONConstants.h" #include "AliRawDataHeader.h" #include #include @@ -359,8 +360,8 @@ void AliHLTMUONTriggerReconstructor::AliDecoderHandler::SelectYPatterns( // here is to perform the bitwise or to form the correct strip pattern. UShort_t mergedPattern[3] = {patterns[i][0], patterns[i][1], patterns[i][2]}; const AliHLTMUONTriggerRecoLutRow& lutnext = fLookupTable.fRow[fCurrentCrateId][locIdnext][i][1][0]; - const AliHLTMUONTriggerRecoLutRow& lutcurr = fLookupTable.fRow[fCurrentCrateId][locIdnext][i][1][0]; - const AliHLTMUONTriggerRecoLutRow& lutprev = fLookupTable.fRow[fCurrentCrateId][locIdnext][i][1][0]; + const AliHLTMUONTriggerRecoLutRow& lutcurr = fLookupTable.fRow[fCurrentCrateId][locIdcurr][i][1][0]; + const AliHLTMUONTriggerRecoLutRow& lutprev = fLookupTable.fRow[fCurrentCrateId][locIdprev][i][1][0]; if (lutprev.fX == lutcurr.fX and lutprev.fY == lutcurr.fY and lutprev.fZ == lutcurr.fZ) { mergedPattern[0] |= patterns[i][1]; @@ -385,7 +386,7 @@ void AliHLTMUONTriggerReconstructor::AliDecoderHandler::SelectYPatterns( else if (xpos[i] >= 0) { strips[i] = mergedPattern[0]; - locId[i] = locIdnext; + locId[i] = locIdprev; } else { @@ -927,7 +928,7 @@ void AliHLTMUONTriggerReconstructor::AliDecoderHandler::ProcessLocalStruct() if (hitset[i]) continue; // Leave the found hits alone. if (stripPosX[i] != -1) { - // Got X strip but no hit so Y strip is missing. + // Got X strip but no hit, so Y strip is missing. // Thus we have a good Y coordinate but poor X. const AliHLTMUONTriggerRecoLutRow& lut = GetLutRowX(stripPosX[i], i); trigger.fHit[i].fFlags = lut.fIdFlags; @@ -939,7 +940,7 @@ void AliHLTMUONTriggerReconstructor::AliDecoderHandler::ProcessLocalStruct() } else if (stripPosY[i] != -1) { - // Got Y strip but no hit so X strip is missing. + // Got Y strip but no hit, so X strip is missing. // Thus we have a good X coordinate but poor Y. const AliHLTMUONTriggerRecoLutRow& lut = fLookupTable.fRow[fCurrentCrateId][locId[i]][i][1][stripPosY[i]]; @@ -953,6 +954,41 @@ void AliHLTMUONTriggerReconstructor::AliDecoderHandler::ProcessLocalStruct() } } } + + // If 4 hits found then check if they are all good, otherwise find the 3 + // best fitting ones. + if (hitCount > 3) + { + AliHLTFloat32_t dx = AliMUONConstants::TriggerNonBendingReso(); + AliHLTFloat32_t dy = AliMUONConstants::TriggerBendingReso(); + AliHLTMUONCalculations::SigmaX2(dx*dx); + AliHLTMUONCalculations::SigmaY2(dy*dy); + + AliHLTFloat32_t chi2 = AliHLTMUONCalculations::ComputeChi2(trigger, hitset); + if (chi2 != -1 and chi2 > 5.*4) // check 5 sigma cut. + { + // Poor fit so look for best 3 points. + int worstHit = -1; + AliHLTFloat32_t bestchi2 = 1e38; + for (int j = 0; j < 4; j++) + { + bool tmphitset[4] = {true, true, true, true}; + tmphitset[j] = false; + AliHLTFloat32_t tmpchi2 = AliHLTMUONCalculations::ComputeChi2(trigger, tmphitset); + if (tmpchi2 * 4 < chi2 * 3 and tmpchi2 < bestchi2) + { + bestchi2 = tmpchi2; + worstHit = j; + } + } + if (worstHit != -1) + { + for (int j = 0; j < 4; j++) hitset[j] = true; + hitset[worstHit] = false; + trigger.fHit[worstHit] = AliHLTMUONConstants::NilRecHitStruct(); + } + } + } // Construct the ID from the running counter fTrigRecId and use the // regional counter, local counter and DDL id for the bottom 8 bits. @@ -1043,7 +1079,7 @@ void AliHLTMUONTriggerReconstructor::AliDecoderHandler::ProcessLocalStruct() } catch (...) { - HLTError("Could not allocate buffer space for debug information."); + HLTError("Could not allocate more buffer space for debug information."); return; } for (AliHLTUInt32_t i = 0; i < fInfoBufferSize; ++i) newbuf[i] = fInfoBuffer[i]; diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructorComponent.cxx b/HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructorComponent.cxx index 40791884b1e..400bc472e36 100644 --- a/HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructorComponent.cxx +++ b/HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructorComponent.cxx @@ -905,9 +905,20 @@ int AliHLTMUONTriggerReconstructorComponent::ReadConfigFromCDB( if (setBL) { - result = GetFloatFromTMap(map, "bfieldintegral", value, pathToEntry, "integrated magnetic field"); - if (result != 0) return result; - AliHLTMUONCalculations::QBL(value); + Double_t bfieldintegral; + result = FetchFieldIntegral(bfieldintegral); + if (result == 0) + { + AliHLTMUONCalculations::QBL(bfieldintegral); + } + else + { + HLTWarning("Failed to load the magnetic field integral from GRP information."); + result = GetFloatFromTMap(map, "bfieldintegral", value, pathToEntry, "integrated magnetic field"); + if (result != 0) return result; + HLTWarning(Form("Using deprecated magnetic field integral value of %f T.m.", value)); + AliHLTMUONCalculations::QBL(value); + } } HLTDebug("Using the following configuration parameters:"); diff --git a/HLT/MUON/macros/CreateCDBFieldIntegrals.C b/HLT/MUON/macros/CreateCDBFieldIntegrals.C new file mode 100644 index 00000000000..2e3a5d74d54 --- /dev/null +++ b/HLT/MUON/macros/CreateCDBFieldIntegrals.C @@ -0,0 +1,168 @@ +/************************************************************************** + * This file is property of and copyright by the ALICE HLT Project * + * All rights reserved. * + * * + * Primary Authors: * + * Artur Szostak * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +// $Id: DisplaydHLTData.C 37070 2009-11-20 13:53:08Z aszostak $ + +/** + * \ingroup macros + * \file CreateCDBFieldIntegrals.C + * \brief Macro for creating and storing the magnetic field integrals in the CDB. + * + * This macro calculates the magnetic field integrals for the dipole magnet and + * writes them into the CDB under the HLT/ConfigMUON/FieldIntegrals path. + * These are then used by the online dHLT reconstruction components during + * momentum estimation of the tracks found. + * The simplest method to run this macro is with the following command: + * \code + * > aliroot -b -q -l CreateCDBFieldIntegrals.C + * \endcode + * + * \author Artur Szostak + */ + +#if !defined(__CINT__) || defined(__MAKECINT__) +#include "AliCDBManager.h" +#include "AliCDBStorage.h" +#include "AliCDBEntry.h" +#include "AliGRPManager.h" +#include "AliHLTMUONConstants.h" +#include "AliMagF.h" +#include "TMap.h" +#include "TArrayD.h" +#include "TObjString.h" +#include "TString.h" +#include "TVector3.h" +#include "TMath.h" +#include "TSystem.h" +#include +using std::cout; +using std::cerr; +using std::endl; +#endif + +/** + * Calculates the average magnetic field integral for the dipole magnet given the + * L3 solenoid current and dipole magnet current. + * [in] \param currentL3 The current in the L3 solenoid magnet. + * [in] \param currentDip The current in the dipole magnet. + * [out] \param result The magnetic field integral result. + * [in] \param sqrts The centre of mass energy for the beams. + * [in] \param beamtype The beam type as given the AliMagF, eg. p-p, A-A or none. + * \note The sign of the current indicates the polarity setting for the magnet. + * \returns true if the magnetic field was calculated successfully and false otherwise. + */ +bool CalculateIntegral( + Float_t currentL3, Float_t currentDip, Float_t& result, + Float_t sqrts = 0, const char* beamtype = "none" + ) +{ + AliMagF* fld = AliMagF::CreateFieldMap(currentL3, currentDip, AliMagF::kConvLHC, kFALSE, sqrts, beamtype); + if (fld == NULL) return false; + + TArrayD totals; + for (int theta = 171; theta <= 179; ++theta) + for (int phi = 0; phi < 360; phi += 10) + { + TVector3 dr; + dr.SetMagThetaPhi(1, theta*TMath::Pi()/180., phi*TMath::Pi()/180.); + Double_t dx = 1e-3 * dr.Mag(); + + TVector3 r(0, 0, 0); + int nsteps = 0; + Double_t total = 0; + while (r.Z() > -1700 && nsteps < 10000) + { + Double_t p[3] = {r.X(), r.Y(), r.Z()}; + Double_t b[3]; + fld->Field(p, b); + total += b[0] * dx; + ++nsteps; + r += dr; + } + + totals.Set(totals.GetSize()+1); + totals[totals.GetSize()-1] = total; + } + + result = - TMath::Mean(totals.GetSize(), totals.GetArray()); + Float_t rms = TMath::RMS(totals.GetSize(), totals.GetArray()); + + cout << "Integrated field value = " << result + << " +/- " << rms + << ", for L3 current = " << currentL3 + << ", dipole current = " << currentDip << endl; + return true; +} + +/** + * Calculates the magnetic field integrals for the dipole magnet and stores them + * into the CDB. + * \param cdbPath The path to the local storage. + * \param version The version of the CDB entry. + * \param firstRun = The first run number for which the CDB entry is valid. + * \param lastRun = The last run number for which the CDB entry is valid. + * \param sqrts The centre of mass energy for the beams. + * \param beamtype The beam type as given the AliMagF, eg. p-p, A-A or none. + */ +void CreateCDBFieldIntegrals( + const char* cdbPath = "local://$ALICE_ROOT/OCDB", + Int_t version = 0, + Int_t firstRun = 0, + Int_t lastRun = AliCDBRunRange::Infinity(), + Float_t sqrts = 0, + const char* beamtype = "none" + ) +{ + // Get the CDB manager and storage. + AliCDBManager* cdbManager = AliCDBManager::Instance(); + if (cdbManager == NULL) + { + cerr << "ERROR: Global CDB manager object does not exist." << endl; + return; + } + AliCDBStorage* storage = cdbManager->GetStorage(cdbPath); + if (storage == NULL) + { + cerr << "ERROR: Could not get storage for: " << cdbPath << endl; + return; + } + + const int nL3Current = 5; + const int nDipCurrent = 3; + Float_t currentL3[nL3Current] = {-30e3, -12e3, 0, 12e3, 30e3}; + Float_t currentDip[nDipCurrent] = {-6e3, 0, 6e3}; + + // Create and store the configuration parameters for the trigger reconstructor. + TMap* params = new TMap; + params->SetOwner(kTRUE); + for (int i = 0; i < nL3Current; ++i) + for (int j = 0; j < nDipCurrent; ++j) + { + if (currentL3[i]*currentDip[j] < 0) continue; // Skip invalid combinations. + Float_t bfieldintegral; + if (! CalculateIntegral(currentL3[i], currentDip[j], bfieldintegral, sqrts, beamtype)) continue; + const char* paramName = Form("L3_current=%0.2e;Dipole_current=%0.2e", currentL3[i], currentDip[j]); + const char* paramValue = Form("%8.8f", bfieldintegral); + params->Add(new TObjString(paramName), new TObjString(paramValue)); + } + + const char* path = AliHLTMUONConstants::FieldIntegralsCDBPath(); + AliCDBId id(path, firstRun, lastRun, version); + AliCDBMetaData* metaData = new AliCDBMetaData(); + metaData->SetResponsible("dimuon HLT"); + metaData->SetComment("Magnetic field integral parameters for dimuon HLT."); + storage->Put(params, id, metaData); +} diff --git a/HLT/MUON/macros/CreateDefaultCDBEntries.C b/HLT/MUON/macros/CreateDefaultCDBEntries.C index 7007103894c..3805018b234 100644 --- a/HLT/MUON/macros/CreateDefaultCDBEntries.C +++ b/HLT/MUON/macros/CreateDefaultCDBEntries.C @@ -50,9 +50,9 @@ using std::endl; /** * Generates default CDB entries in the given CDB storage (local by default) * \param cdbPath The path to the local storage. - * \param version = 0, - * \param firstRun = 0, - * \param lastRun = AliCDBRunRange::Infinity() + * \param version The version of the CDB entry. + * \param firstRun = The first run number for which the CDB entry is valid. + * \param lastRun = The last run number for which the CDB entry is valid. * \param zmiddle The middle of the dipole field (cm) used by AliHLTMUONTriggerReconstructorComponent and AliHLTMUONMansoTrackerFSMComponent. * \param bfieldintegral The dipole magnetic field integral (T.m) used by AliHLTMUONTriggerReconstructorComponent and AliHLTMUONMansoTrackerFSMComponent. * \param dccut DC cut applied to channels by AliHLTMUONHitReconstructorComponent. diff --git a/HLT/MUON/macros/DisplaydHLTData.C b/HLT/MUON/macros/DisplaydHLTData.C new file mode 100644 index 00000000000..ba15d6563ea --- /dev/null +++ b/HLT/MUON/macros/DisplaydHLTData.C @@ -0,0 +1,281 @@ +/************************************************************************** + * This file is property of and copyright by the ALICE HLT Project * + * All rights reserved. * + * * + * Primary Authors: * + * Artur Szostak * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +// $Id: DisplaydHLTData.C 37070 2009-11-20 13:53:08Z aszostak $ + +/** + * \ingroup macros + * \file DisplaydHLTData.C + * \brief Macro for displaying rootified dHLT data generated with RunChain.C + * + * This macro is used to display the dHLT data generated by the RunChain.C macro + * with the "root" option for making the output data. Optionally the dHLTRawData.root + * file which is generated during a AliRoot offline reconstruction can also be + * displayed using this macro. + * After having generated the dHLT raw data file (called output.root for example) + * the following command can be executed in an alieve session to display both + * MUON and dHLT data: + * \code + * > gSystem->Load("libAliHLTMUON.so"); + * > .L $ALICE_ROOT/EVE/macros/alieve_init.C + * > .L $ALICE_ROOT/EVE/alice-macros/event_goto.C + * > .L $ALICE_ROOT/EVE/alice-macros/MUON_displayData.C + * > .L $ALICE_ROOT/HLT/MUON/macros/DisplaydHLTData.C + * > alieve_init("OCDBpath","DataPath",EventNumber); + * > MUON_displayData(1,1,1); + * > DisplaydHLTData("output.root"); + * \endcode + * Where OCDBpath should be replaced by the path to the OCDB database, + * DataPath should be the directory of the raw data or raw data root file and + * EventNumber is the event number to load. + * + * \author Artur Szostak + */ + +#if !defined(__CINT__) || defined(__MAKECINT__) +#include "AliEveEventManager.h" +#include "AliHLTMUONTriggerRecord.h" +#include "AliHLTMUONRecHit.h" +#include "AliHLTMUONMansoTrack.h" +#include "AliHLTMUONEvent.h" +#include "TEveManager.h" +#include "TEveElement.h" +#include "TEvePointSet.h" +#include "TEveStraightLineSet.h" +#include "TArrayD.h" +#include "TFile.h" +#include "TString.h" +#include "TClassTable.h" +#include "TSystem.h" +#include +using std::cerr; +using std::endl; +#endif + + +TFile* gDHLTFile = NULL; + +void FillData(Int_t eventId); + + +void DisplaydHLTData(const char* dHLTfilename = "output.root") +{ + // Display dHLT data. + + if (gClassTable->GetID("AliHLTMUONEvent") < 0) + { + gSystem->Load("libAliHLTMUON.so"); + } + + if (AliEveEventManager::GetMaster() == NULL) + { + cerr << "ERROR: alieve event not initialised, use alieve_init(...)" << endl; + return; + } + + gEve->DisableRedraw(); + + TString filename = dHLTfilename; + TString tmpfilename = filename; + if (gSystem->FindFile("", tmpfilename) == NULL) + { + tmpfilename = filename; + if (gSystem->FindFile(".", tmpfilename) == NULL) + { + TString filename = TString(AliEveEventManager::GetMaster()->GetTitle()); + filename += "/"; + filename += dHLTfilename; + } + } + if (gDHLTFile == NULL) + { + gDHLTFile = new TFile(filename.Data(), "READ"); + } + else if (filename != gDHLTFile->GetName()) + { + delete gDHLTFile; + gDHLTFile = new TFile(filename.Data(), "READ"); + } + + FillData(AliEveEventManager::GetMaster()->GetEventId()); + + gEve->Redraw3D(kTRUE); + gEve->EnableRedraw(); +} + + +void FillData(TEveElementList* list, const AliHLTMUONTriggerRecord* trigrec) +{ + // Count the number of points in the trigger record. + Int_t pointCount = 0; + for (int i = 11; i <= 14; ++i) + { + if (trigrec->Hit(i) != TVector3(0,0,0)) ++pointCount; + } + + // Create and fill the point set for the trigger record. + TEvePointSet* pointset = new TEvePointSet(pointCount); + pointset->SetName(Form("TriggerRecord%d", trigrec->Id())); + pointset->SetTitle(Form("dHLT trigger record ID = %d", trigrec->Id())); + pointset->SetMarkerStyle(28); + pointset->SetMarkerColor(kYellow); + pointset->SetMarkerSize(3); + Int_t ipnt = 0; + for (int i = 11; i <= 14; ++i) + { + if (trigrec->Hit(i) == TVector3(0,0,0)) continue; + pointset->SetPoint(ipnt, trigrec->Hit(i).X(), trigrec->Hit(i).Y(), trigrec->Hit(i).Z()); + ++ipnt; + } + + list->AddElement(pointset); +} + + +void FillData(TEveElementList* list, const AliHLTMUONMansoTrack* track) +{ + // Count the points in the track. + Int_t pointCount = 0; + for (int i = 7; i <= 10; ++i) + { + const AliHLTMUONRecHit* hit = track->Hit(i); + if (hit != NULL) ++pointCount; + } + const AliHLTMUONTriggerRecord* trigrec = track->TriggerRecord(); + if (trigrec != NULL) + { + for (int i = 11; i <= 14; ++i) + { + if (trigrec->Hit(i) != TVector3(0,0,0)) ++pointCount; + } + } + + // Create and fill the point set for the track. + TEvePointSet* pointset = new TEvePointSet(pointCount); + pointset->SetName(Form("Track%d", track->Id())); + pointset->SetTitle(Form("dHLT track ID = %d", track->Id())); + if (track->Id() != -1) + { + pointset->SetMarkerStyle(20); + pointset->SetMarkerColor(kGreen); + pointset->SetMarkerSize(1.5); + } + else + { + pointset->SetMarkerStyle(28); + pointset->SetMarkerColor(kYellow); + pointset->SetMarkerSize(3); + } + Int_t ipnt = 0; + if (trigrec != NULL) + { + for (int i = 11; i <= 14; ++i) + { + if (trigrec->Hit(i) == TVector3(0,0,0)) continue; + pointset->SetPoint(ipnt, trigrec->Hit(i).X(), trigrec->Hit(i).Y(), trigrec->Hit(i).Z()); + ++ipnt; + } + } + for (int j = 7; j <= 10; ++j) + { + const AliHLTMUONRecHit* hit = track->Hit(j); + if (hit == NULL) continue; + pointset->SetPoint(ipnt, hit->X(), hit->Y(), hit->Z()); + ++ipnt; + } + + for (int j = 7; j <= 10; ++j) + { + if (track->RoIRadius(j) == -1) continue; + TEveStraightLineSet* roi = new TEveStraightLineSet( + Form("RoI%d", j), + Form("Region of interest for chamber %d", j) + ); + Float_t p0x = track->RoICentre(j).X() + track->RoIRadius(j); + Float_t p0y = track->RoICentre(j).Y(); + Float_t p0z = track->RoICentre(j).Z(); + Float_t p1x = p0x; + Float_t p1y = p0y; + Float_t p1z = p0z; + for (int i = 0; i < 32; ++i) + { + Double_t t = Double_t(i) / 32. * 2. * TMath::Pi(); + Float_t p2x = track->RoICentre(j).X() + track->RoIRadius(j)*cos(t); + Float_t p2y = track->RoICentre(j).Y() + track->RoIRadius(j)*sin(t); + Float_t p2z = track->RoICentre(j).Z(); + roi->AddLine(p1x, p1y, p1z, p2x, p2y, p2z); + p1x = p2x; + p1y = p2y; + p1z = p2z; + } + roi->AddLine(p1x, p1y, p1z, p0x, p0y, p0z); + pointset->AddElement(roi); + } + + list->AddElement(pointset); +} + + +void FillData(Int_t eventId) +{ + AliHLTMUONEvent* dhltEvent = dynamic_cast( gDHLTFile->Get(Form("AliHLTMUONEvent;%d", eventId+1)) ); + if (dhltEvent == NULL) + { + cerr << "ERROR: Could not find dHLT data for event " << eventId << endl; + return; + } + + TEveElementList* list = new TEveElementList("dHLTData", "dHLT data"); + gEve->AddElement(list); + + TArrayD px, py, pz; + for (int i = 0; i < dhltEvent->DataObjects().GetEntriesFast(); i++) + { + if (dhltEvent->DataObjects()[i]->IsA() == AliHLTMUONRecHit::Class()) + { + const AliHLTMUONRecHit* hit = dynamic_cast( dhltEvent->DataObjects()[i] ); + px.Set(px.GetSize()+1); + py.Set(py.GetSize()+1); + pz.Set(pz.GetSize()+1); + px[px.GetSize()-1] = hit->X(); + py[py.GetSize()-1] = hit->Y(); + pz[pz.GetSize()-1] = hit->Z(); + continue; + } + else if (dhltEvent->DataObjects()[i]->IsA() == AliHLTMUONTriggerRecord::Class()) + { + const AliHLTMUONTriggerRecord* trigrec = dynamic_cast( dhltEvent->DataObjects()[i] ); + FillData(list, trigrec); + } + else if (dhltEvent->DataObjects()[i]->IsA() == AliHLTMUONMansoTrack::Class()) + { + const AliHLTMUONMansoTrack* track = dynamic_cast( dhltEvent->DataObjects()[i] ); + FillData(list, track); + } + } + + TEvePointSet* mps = new TEvePointSet(px.GetSize()); + mps->SetName("RecHits"); + mps->SetTitle("dHLT reconstructed hits"); + mps->SetMarkerStyle(28); + mps->SetMarkerColor(kYellow); + mps->SetMarkerSize(3); + for (int i = 0; i < px.GetSize(); ++i) + { + mps->SetPoint(i, px[i], py[i], pz[i]); + } + list->AddElement(mps); +} diff --git a/HLT/MUON/macros/RunChain.C b/HLT/MUON/macros/RunChain.C index ff39b6123dd..8bef234018e 100644 --- a/HLT/MUON/macros/RunChain.C +++ b/HLT/MUON/macros/RunChain.C @@ -43,6 +43,7 @@ #if !defined(__CINT__) || defined(__MAKECINT__) #include "AliRawReader.h" #include "AliHLTOfflineInterface.h" +#include "AliCDBStorage.h" #include "AliCDBManager.h" #include "AliHLTSystem.h" #include "AliHLTConfiguration.h" @@ -485,7 +486,12 @@ void RunChain( // full chains. if (buildTrackerComp) { - AliHLTConfiguration tracker("tracker", "MUONMansoTrackerFSM", "recDDL13 recDDL14 recDDL15 recDDL16 recDDL17 recDDL18 recDDL19 recDDL20 recDDL21 recDDL22", ""); + AliHLTConfiguration tracker( + "tracker", + "MUONMansoTrackerFSM", + "recDDL13 recDDL14 recDDL15 recDDL16 recDDL17 recDDL18 recDDL19 recDDL20 recDDL21 recDDL22", + "-makecandidates" + ); } // Build the dHLT trigger decision component if enabled. diff --git a/OCDB/HLT/ConfigMUON/FieldIntegrals/Run0_999999999_v0_s0.root b/OCDB/HLT/ConfigMUON/FieldIntegrals/Run0_999999999_v0_s0.root new file mode 100644 index 0000000000000000000000000000000000000000..4ab739b7838b6184f7e3b285ba95faf3f0c4bbb5 GIT binary patch literal 2603 zcmcguc{J4h8vl*Vi;+EhjitttWo(lrWMXWuwMZz-)L@tyjIoS}?Awqql1TQgQpgeE zwU!pH7pcKp$UYgeWyw3{o_p^7@80`Q-*cYt_c`Z#p5^mA-|zE0M1Ox00KBaO0N^?R zK$HN0tANR;GYQ0`dG>!YN5TLA>AgW~Mc!N(WOc4ugjK_~S8fPa-Lp2sgKKPzfOV`(mz<;7AAE%y*L_aHS@;vvLeVFLgk z;$vY1fEFgac_y)N0s!aKe+wRnaTp_T8%tjEFh-!HLwRmy6qv|S1QL<_pFH4V#n}J? z+Q2{BDD%c7%WHh2_1!O2Y7i>wQ`S4jpshP1 zZMSU8H07%N0xgCWF&_&){+RXFG<@5B9vr0*w7vCkXDxk*r&AqYXk?KC`DQK>fQ@n? zsXiIFbJy(1(DIDUv4)R0n&``29WVQ56?rc(bvz}LKC7!fugW3D+VkTbZwkZWaq}J+S>#5KLp|-Jp($0V*LrXGn7xr_gt(!R}s5P52G&Vx`|u4 z6@07~Mk`N*SoLXHiK_29pJ_p#xp$k=aP}T>K@(n6oC~Iha=rd^GGHcH^J>jEJ8Y`Z zoj^-DEts&Oj&q`AblXNHqvy5J4_zv1NamS27!T2X)}J%IcfftRFV7~fZx8VvL{ZTZ z*zz-@e;fTnVevaMU{ZHNZw40@d>n@3PwYAiZfu0pr$X`ZttzRL`~YRHDb&RxJIP=h z5R!;}Cv(n+&Y{fZ>M1znSm<76f4L0l(lXVwRbq}(hJr35b&@W3-tc`eb%88$SC4m^ zL4_%|UED3Xy#Jzn7x=xtMC|hsnMW`-)^}p&n-9;*x6xs~4?h`j9qeF*4I&-ANFri9 z@fe~7!OLIJ#6K8~BTM731V7Am<`G090RVDo{AUMu1C^(m*q#dV2 zL`_9~?oM9I{}`;{*JFPrS#3x^Wc}UV>~3U6-UxQIJg}cXMNT4{tDr$jszhtizJtQc zSN-^_fS1$-8~JeP6cH)X84v4Ib+U9CR~S3F@?eke?i-`^$KxK2kf_%%bH~_yI2rA`Gv4dU)hdDY z$%VP4OxHRhg085&trnIIm)!6heh3qlEc0D7p+iZic9g`YeBxHF1Ac83l984oAl_`F zA&t!~LENLL@A$=|X^MtrWQiMX4YP7s{-j4gs#6N)Rn4j#&)hz{b?+Xt$Ss1sd;;Cr-P)fX4C|lQ7^J|kz2soK)XIsLnk`?LPJ+oq9 zk-wQ=O4rSK9w}AaPHlJZAV^#9@~$yAuiFh=po#|y*nETjJ@!|6SRbcT7K&XNu70K@ z?{TxN3LRfUk(5h0IzuFNU5C)U={v5LQ`G9X^a9a^{~j?I>@00M=E^=NKKu|Pm#_dI z^}Geex)(bk$oBF5&P$v;v>^GWX=uK;eV<(-b+uX&kJ8J`#6@LkMU24gpH$LBYr~uJ zq^;s7X0xIrMoX5TjQteiTD!$wRV`gni#eILm?tU?z;hjqN0ei?iS^5Spr#2zoi#kPNH)29 z7VDFDH8nss4^7?G)Wc@wRIL3i zezQD|m)qq(9TH}_Pgfkt%QQSF+0=Z^c#HE8?$oT;6DyRxX{)3EE>3A9#3nGO>G3C| zm`vAz3%aA!Q;fiMe`A~6lJmLJzv6>K8&RVSBF0g*0l=an#O!kMTT|DY5yP_kW>ACh zz4wtgRl!-dOUZF$&q3J($)@b(U2*_5E%Yu?I!sZIa;M{CeDFD5ifA;5W5*N*A`pv%+6iEjreXvhk&% z&hWX1;7q9Au&BGr-I2bo+w}D<6ab%$$Ynm#r@bj({%k*!A8Ny_sV%JOLz`7;S#4mH5={Q6w6p;=54OWUkGXMYp literal 0 HcmV?d00001 -- 2.43.0