]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Important updates for Manso Tracker to use magnetic field integrals based on global...
authoraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 23 Nov 2009 11:08:09 +0000 (11:08 +0000)
committeraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 23 Nov 2009 11:08:09 +0000 (11:08 +0000)
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.

22 files changed:
HLT/MUON/AliHLTMUONConstants.cxx
HLT/MUON/AliHLTMUONConstants.h
HLT/MUON/AliHLTMUONMansoTrack.cxx
HLT/MUON/AliHLTMUONMansoTrack.h
HLT/MUON/AliHLTMUONProcessor.cxx
HLT/MUON/AliHLTMUONProcessor.h
HLT/MUON/AliHLTMUONTriggerRecord.cxx
HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.cxx
HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.h
HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.h
HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSM.h
HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.h
HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructor.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructorComponent.cxx
HLT/MUON/macros/CreateCDBFieldIntegrals.C [new file with mode: 0644]
HLT/MUON/macros/CreateDefaultCDBEntries.C
HLT/MUON/macros/DisplaydHLTData.C [new file with mode: 0644]
HLT/MUON/macros/RunChain.C
OCDB/HLT/ConfigMUON/FieldIntegrals/Run0_999999999_v0_s0.root [new file with mode: 0644]

index ca4eaaf2298c0f76caf91122232e4e8431a339bc..6a7f7216aa94a569979eb4602836df89a7ca786c 100644 (file)
@@ -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";
index 215a6d3ee6501b074df49e9a642650efcbd94919..955ba492e23225c70e66b97313eb17c5fdebd6f4 100644 (file)
@@ -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.
 };
index e3259fd51b77e19c254439b506f0738f648456b1..0ec164f1d20e8dc5c8c15f612033c77bbdb95b2c 100644 (file)
@@ -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)
+               ));
+       }
+}
index 2877dbb9f2a22086125ed634f42c634dc4f3fbfb..7c85e68ad58e683d7f07d9ac9c41e1821fe18ca1 100644 (file)
@@ -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.
index f3281426de57a9e8fefd7a1e1b62927ccb731def..6dc71a8d32c3b6838f091a88b235b5d80bf404a0 100644 (file)
 ///
 
 #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<AliMagF*>(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.
index d788f108d35ecc245f3d5bb3a3828286d39b6f5b..35710cf1a34d4c67edeafc81e1eb47cb55eed11a 100644 (file)
@@ -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
index 812f83c3977fbfc128950447eddb1c8f1e5036da..b096a6f6d7e46d6366a92e00949a9656e6bce73a 100644 (file)
@@ -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"
index c3120abef66394bae383d360a7ac347b7cbcb5ea..f4d7771cd8ebaaf124f231794ae8ad0e786e399f 100644 (file)
@@ -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<AliHLTInt32_t, AliHLTMUONMansoTrack*> 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<const AliHLTMUONTriggerRecord*>(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<const AliHLTMUONRecHit*>(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<const AliHLTMUONTriggerRecord*>(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<const AliHLTMUONRecHit*>(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;
+}
index 326985143802af23fc26e3e9b716f44c1b74e800..6fc0cd473306f2771fd4df855deae2fda327cad1 100644 (file)
 
 #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.
index 96e698c5a8fd8e9c06d4c3dd274ae3b413e15290..cfe1613874489e33796a1938092602178773fe8d 100644 (file)
@@ -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;
+}
index 9f77b170b518bf875aaee0c4367f5217e5a250c8..8208122b68293280b08c1ab30890f0e604b0f822 100644 (file)
@@ -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; }
index 7c387a1fb86b7acad394083fc0bfc2f1a6026399..be4b35b6e88351dad2261c297dc26379eacabf94 100644 (file)
@@ -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 <cmath>
 
 
@@ -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++];
+}
index 4a9c18402f9c9e35c7277431c83db6244cd48970..a8ca52d475f31cb2eb5156e7baa324530e3029e6 100644 (file)
@@ -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.                  *
  **************************************************************************/
 
 ///  @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 <cassert>
 
+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:
 
index 380df05ff1c870586ec4489bac30fc84444e3957..01655d6963cbf54a09dbca212a217028fca50c0f 100644 (file)
@@ -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;
 }
 
index fed3f5f95773d90e9a4677720367668c462e605b..b63415c18cfb87cd5ca8705aa914bef459a9fe7f 100644 (file)
@@ -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 <i>path</i> <br>
  *      Allows one to specify the path in which to dump the received data blocks
  *      if an error occurs. <br>
+ * \li -makecandidates <br>
+ *      Indicates if the Manso track candidates data block should be generated.
+ *      This kind of information is useful for debugging. <br>
  *
  * <h2>Standard configuration:</h2>
  * This component should normally be configured with no extra options.
index a1114b58a66bad9a31a2fa0b725b4bd09607e48b..64bae02d3f3b29d19756c85ad051e238e09e2d63 100644 (file)
@@ -46,6 +46,7 @@
 #include "AliHLTMUONUtils.h"
 #include "AliHLTMUONConstants.h"
 #include "AliHLTMUONCalculations.h"
+#include "AliMUONConstants.h"
 #include "AliRawDataHeader.h"
 #include <vector>
 #include <cassert>
@@ -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];
index 40791884b1e7bb83ac271df20424798e2519b60e..400bc472e36379f159063cb39a1b87f1361dedc9 100644 (file)
@@ -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 (file)
index 0000000..2e3a5d7
--- /dev/null
@@ -0,0 +1,168 @@
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        *
+ * All rights reserved.                                                   *
+ *                                                                        *
+ * Primary Authors:                                                       *
+ *   Artur Szostak <artursz@iafrica.com>                                  *
+ *                                                                        *
+ * 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 <artursz@iafrica.com>
+ */
+
+#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 <iostream>
+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);
+}
index 7007103894c69c11ec013fdfce507254e877d518..3805018b2342e978991693e28dc13d95e7d966b6 100644 (file)
@@ -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 (file)
index 0000000..ba15d65
--- /dev/null
@@ -0,0 +1,281 @@
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        *
+ * All rights reserved.                                                   *
+ *                                                                        *
+ * Primary Authors:                                                       *
+ *   Artur Szostak <artursz@iafrica.com>                                  *
+ *                                                                        *
+ * 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 <i>output.root</i> 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 <i>OCDBpath</i> should be replaced by the path to the OCDB database,
+ * <i>DataPath</i> should be the directory of the raw data or raw data root file and
+ * <i>EventNumber</i> is the event number to load.
+ *
+ * \author Artur Szostak <artursz@iafrica.com>
+ */
+
+#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 <iostream>
+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<AliHLTMUONEvent*>( 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<const AliHLTMUONRecHit*>( 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<const AliHLTMUONTriggerRecord*>( dhltEvent->DataObjects()[i] );
+                       FillData(list, trigrec);
+               }
+               else if (dhltEvent->DataObjects()[i]->IsA() == AliHLTMUONMansoTrack::Class())
+               {
+                       const AliHLTMUONMansoTrack* track = dynamic_cast<const AliHLTMUONMansoTrack*>( 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);
+}
index ff39b6123ddbff68a0bed1e4677196d9142b0863..8bef234018e3d8afc2825824fc2aa72b8ca1ddd1 100644 (file)
@@ -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 (file)
index 0000000..4ab739b
Binary files /dev/null and b/OCDB/HLT/ConfigMUON/FieldIntegrals/Run0_999999999_v0_s0.root differ