From ed68e115961dda14fa3932ec909dd70e36bf762b Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 23 Jan 2017 01:59:08 +0100 Subject: [PATCH 1/7] Fixed dependencies for modified Common/Field --- cmake/O2Dependencies.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/O2Dependencies.cmake b/cmake/O2Dependencies.cmake index 273f17314cc44..13946f2f6d4a6 100644 --- a/cmake/O2Dependencies.cmake +++ b/cmake/O2Dependencies.cmake @@ -1,4 +1,5 @@ + ########## DEPENDENCIES lookup ############ find_package(ROOT 6.06.00 REQUIRED) @@ -186,9 +187,11 @@ o2_define_bucket( common_field_bucket DEPENDENCIES - Core RIO MathUtils Geom + fairroot_base_bucket + Base ParBase Core RIO MathUtils Geom INCLUDE_DIRECTORIES + ${FAIRROOT_INCLUDE_DIR} ${ROOT_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/Common/MathUtils/include ) From b169f04274b3449037527427a1415ccc7edd62c9 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 23 Jan 2017 02:00:24 +0100 Subject: [PATCH 2/7] B-field map complies with FairField --- Common/Field/include/Field/MagneticField.h | 95 +++++++++-- Common/Field/src/FieldLinkDef.h | 1 + Common/Field/src/MagneticField.cxx | 187 +++++++++++++++++---- 3 files changed, 234 insertions(+), 49 deletions(-) diff --git a/Common/Field/include/Field/MagneticField.h b/Common/Field/include/Field/MagneticField.h index 6302699157550..64563b01a85b9 100644 --- a/Common/Field/include/Field/MagneticField.h +++ b/Common/Field/include/Field/MagneticField.h @@ -5,22 +5,27 @@ #ifndef ALICEO2_FIELD_MAGNETICFIELD_H_ #define ALICEO2_FIELD_MAGNETICFIELD_H_ -#include // for TVirtualMagField +#include "FairField.h" // for FairField +#include "FairParGenericSet.h" +#include "Field/MagneticWrapperChebyshev.h" // for MagneticWrapperChebyshev #include "TSystem.h" #include "Rtypes.h" // for Double_t, Char_t, Int_t, Float_t, etc #include "TNamed.h" // for TNamed class FairLogger; // lines 14-14 +class FairParamList; + namespace AliceO2 { namespace Field { class MagneticWrapperChebyshev; }} // lines 19-19 namespace AliceO2 { namespace Field { +class MagFieldParam; class MagneticWrapperChebyshev; - + /// Interface between the TVirtualMagField and MagneticWrapperChebyshev: wrapper to the set of magnetic field data + /// Tosca /// parametrization by Chebyshev polynomials -class MagneticField : public TVirtualMagField +class MagneticField : public FairField { public: @@ -53,16 +58,48 @@ class MagneticField : public TVirtualMagField std::string("/Common/maps/mfchebKGI_sym.root") ); - MagneticField(const MagneticField &src); + + MagneticField(const MagFieldParam& param); MagneticField &operator=(const MagneticField &src); /// Default destructor - virtual ~MagneticField(); + virtual ~MagneticField() {} + + /// real field creation is here + void CreateField(); + + /// Virtual methods from FairField + + /// X component, avoid using since slow + virtual Double_t GetBx(Double_t x, Double_t y, Double_t z) { + double xyz[3]={x,y,z},b[3]; + GetFieldValue(xyz,b); + return b[0]; + } + + /// Y component, avoid using since slow + virtual Double_t GetBy(Double_t x, Double_t y, Double_t z) { + double xyz[3]={x,y,z},b[3]; + GetFieldValue(xyz,b); + return b[1]; + } + + /// Z component + virtual Double_t GetBz(Double_t x, Double_t y, Double_t z) { + double xyz[3]={x,y,z}; + return getBz(xyz); + } /// Method to calculate the field at point xyz - virtual void Field(const Double_t *x, Double_t *b); + virtual void GetFieldValue(const Double_t point[3], Double_t* bField); + + /// 3d field query alias for Alias Method to calculate the field at point xyz + virtual void GetBxyz(const Double_t p[3], Double_t* b) {Field(p,b);} + /// Fill Paramater + virtual void FillParContainer(); + /// Method to calculate the integral_0^z of br,bt,bz void getTPCIntegral(const Double_t *xyz, Double_t *b) const; @@ -79,10 +116,7 @@ class MagneticField : public TVirtualMagField /// Method to calculate the field at point xyz Double_t getBz(const Double_t *xyz) const; - MagneticWrapperChebyshev *getMeasuredMap() const - { - return mMeasuredMap; - } + MagneticWrapperChebyshev *getMeasuredMap() const { return mMeasuredMap.get();} // Former MagF methods or their aliases @@ -215,7 +249,7 @@ class MagneticField : public TVirtualMagField } protected: - MagneticWrapperChebyshev *mMeasuredMap; //! Measured part of the field map + std::unique_ptr mMeasuredMap; //! Measured part of the field map BMap_t mMapType; ///< field map type Double_t mSolenoid; ///< Solenoid field setting BeamType_t mBeamType; ///< Beam type: A-A (mBeamType=0) or p-p (mBeamType=1) @@ -234,16 +268,53 @@ class MagneticField : public TVirtualMagField Double_t mCompensatorField1A; ///< Side A 1st compensator field Double_t mCompensatorField2A; ///< Side A 2nd compensator field - TNamed mParameterNames; ///< file and parameterization loadad + TNamed mParameterNames; ///< file and parameterization loaded static const Double_t sSolenoidToDipoleZ; ///< conventional Z of transition from L3 to Dipole field static const UShort_t sPolarityConvention; ///< convention for the mapping of the curr.sign on main component sign FairLogger *mLogger; + private: + MagneticField(const MagneticField &src); + + + ClassDef(AliceO2::Field::MagneticField, 2) // Class for all Alice MagField wrapper for measured data + Tosca parameterization }; + +class MagFieldParam : public FairParGenericSet +{ + public: + MagFieldParam(const char* name="", const char* title="", const char* context=""); + + void SetParam(const MagneticField* field); + + MagneticField::BMap_t GetMapType() const {return mMapType;} + MagneticField::BeamType_t GetBeamType() const {return mBeamType;} + Int_t GetDefInt() const {return mDefaultIntegration;} + Double_t GetFactorSol() const {return mFactorSol;} + Double_t GetFactorDip() const {return mFactorDip;} + Double_t GetBeamEnergy() const {return mBeamEnergy;} + Double_t GetMaxField() const {return mMaxField;} + const char* GetMapPath() const {return mMapPath.Data();} + + virtual void putParams(FairParamList* list); + virtual Bool_t getParams(FairParamList* list); + + protected: + MagneticField::BMap_t mMapType; ///< map type ID + MagneticField::BeamType_t mBeamType; ///< beam type ID + Int_t mDefaultIntegration; ///< field integration type for MC + Double_t mFactorSol; ///< solenoid current factor + Double_t mFactorDip; ///< dipole current factor + Double_t mBeamEnergy; ///< beam energy + Double_t mMaxField; ///< max field for geant + TString mMapPath; ///< path to map file + + ClassDef(MagFieldParam,1) +}; } } diff --git a/Common/Field/src/FieldLinkDef.h b/Common/Field/src/FieldLinkDef.h index 403a8481c2518..cf97195ebc19c 100644 --- a/Common/Field/src/FieldLinkDef.h +++ b/Common/Field/src/FieldLinkDef.h @@ -6,5 +6,6 @@ #pragma link C++ class AliceO2::Field::MagneticField+; #pragma link C++ class AliceO2::Field::MagneticWrapperChebyshev+; +#pragma link C++ class AliceO2::Field::MagFieldParam+; #endif diff --git a/Common/Field/src/MagneticField.cxx b/Common/Field/src/MagneticField.cxx index a9b959b60b99b..a75b23d6a9353 100644 --- a/Common/Field/src/MagneticField.cxx +++ b/Common/Field/src/MagneticField.cxx @@ -3,11 +3,13 @@ /// \author ruben.shahoyan@cern.ch #include "Field/MagneticField.h" -#include "Field/MagneticWrapperChebyshev.h" // for MagneticWrapperChebyshev #include // for TFile #include // for TPRegexp #include // for TSystem, gSystem #include "FairLogger.h" // for FairLogger, MESSAGE_ORIGIN +#include "FairParamList.h" +#include "FairRun.h" +#include "FairRuntimeDb.h" using namespace AliceO2::Field; @@ -51,8 +53,8 @@ Double_t MagneticField::sSolenoidToDipoleZ = -700.; const UShort_t MagneticField::sPolarityConvention = MagneticField::kConvLHC; MagneticField::MagneticField() - : TVirtualMagField(), - mMeasuredMap(0), + : FairField(), + mMeasuredMap(nullptr), mMapType(k5kG), mSolenoid(0), mBeamType(kNoBeamField), @@ -71,21 +73,22 @@ MagneticField::MagneticField() mParameterNames("", ""), mLogger(FairLogger::GetLogger()) { + fType = 2; // flag non-constant field } MagneticField::MagneticField(const char *name, const char *title, Double_t factorSol, Double_t factorDip, BMap_t maptype, BeamType_t bt, Double_t be, Int_t integ, Double_t fmax, const std::string path) - : TVirtualMagField(name), - mMeasuredMap(0), + : FairField(name,title), + mMeasuredMap(nullptr), mMapType(maptype), mSolenoid(0), mBeamType(bt), mBeamEnergy(be), mDefaultIntegration(integ), mPrecisionInteg(1), - mMultipicativeFactorSolenoid(1.), - mMultipicativeFactorDipole(1.), + mMultipicativeFactorSolenoid(factorSol), + mMultipicativeFactorDipole(factorDip), mMaxField(fmax), mDipoleOnOffFlag(factorDip == 0.), mQuadrupoleGradient(0), @@ -96,25 +99,53 @@ MagneticField::MagneticField(const char *name, const char *title, Double_t facto mParameterNames("", ""), mLogger(FairLogger::GetLogger()) { - SetTitle(title); - if (integ < 0 || integ > 2) { - mLogger->Warning(MESSAGE_ORIGIN, "Invalid magnetic field flag: %5d; Helix tracking chosen instead", integ); + setDataFileName(path.c_str()); + CreateField(); +} + +MagneticField::MagneticField(const MagFieldParam& param) + : FairField(param.GetName(),param.GetTitle()), + mMeasuredMap(nullptr), + mMapType(param.GetMapType()), + mSolenoid(0), + mBeamType(param.GetBeamType()), + mBeamEnergy(param.GetBeamEnergy()), + mDefaultIntegration(param.GetDefInt()), + mPrecisionInteg(1), + mMultipicativeFactorSolenoid(param.GetFactorSol()), // temporary + mMultipicativeFactorDipole(param.GetFactorDip()), // temporary + mMaxField(param.GetMaxField()), + mDipoleOnOffFlag(param.GetFactorDip() == 0.), + mQuadrupoleGradient(0), + mDipoleField(0), + mCompensatorField2C(0), + mCompensatorField1A(0), + mCompensatorField2A(0), + mParameterNames("", ""), + mLogger(FairLogger::GetLogger()) +{ + setDataFileName(param.GetMapPath()); + CreateField(); +} + +void MagneticField::CreateField() +{ + fType = 2; // flag non-constant field + + // does real creation of the field + if (mDefaultIntegration < 0 || mDefaultIntegration > 2) { + mLogger->Warning(MESSAGE_ORIGIN, "Invalid magnetic field flag: %5d; Helix tracking chosen instead", + mDefaultIntegration); mDefaultIntegration = 2; } - if (mDefaultIntegration == 0) { - mPrecisionInteg = 0; - } + if (mDefaultIntegration == 0) mPrecisionInteg = 0; if (mBeamEnergy <= 0 && mBeamType != kNoBeamField) { - if (mBeamType == kBeamTypepp) { - mBeamEnergy = 7000.; // max proton energy - } - else if (mBeamType == kBeamTypeAA) { - mBeamEnergy = 2760; // max PbPb energy - } - else if (mBeamType == kBeamTypepA || mBeamType == kBeamTypeAp) { + if (mBeamType == kBeamTypepp) mBeamEnergy = 7000.; // max proton energy + else if (mBeamType == kBeamTypeAA) mBeamEnergy = 2760; // max PbPb energy + else if (mBeamType == kBeamTypepA || mBeamType == kBeamTypeAp) mBeamEnergy = 2760; // same rigitiy max PbPb energy - } + // FairLogger::GetLogger()->Info(MESSAGE_ORIGIN, "Maximim possible beam energy for requested beam is assumed"); } @@ -130,21 +161,23 @@ MagneticField::MagneticField(const char *name, const char *title, Double_t facto mLogger->Fatal(MESSAGE_ORIGIN, "Unknown field identifier %d is requested\n", mMapType); } - setDataFileName(path.c_str()); setParameterName(parname); loadParameterization(); initializeMachineField(mBeamType, mBeamEnergy); + setFactorSolenoid(mMultipicativeFactorSolenoid); + setFactorDipole(mMultipicativeFactorDipole); double xyz[3] = {0., 0., 0.}; mSolenoid = getBz(xyz); - setFactorSolenoid(factorSol); - setFactorDipole(factorDip); Print("a"); + // } +/* + RS: not needed, FairField has no copy c-tor implemented MagneticField::MagneticField(const MagneticField &src) - : TVirtualMagField(src), - mMeasuredMap(0), + : FairField(src), + mMeasuredMap(nullptr), mMapType(src.mMapType), mSolenoid(src.mSolenoid), mBeamType(src.mBeamType), @@ -164,14 +197,11 @@ MagneticField::MagneticField(const MagneticField &src) mLogger(FairLogger::GetLogger()) { if (src.mMeasuredMap) { - mMeasuredMap = new MagneticWrapperChebyshev(*src.mMeasuredMap); + mMeasuredMap(new MagneticWrapperChebyshev(*src.mMeasuredMap)); } } +*/ -MagneticField::~MagneticField() -{ - delete mMeasuredMap; -} Bool_t MagneticField::loadParameterization() { @@ -185,7 +215,8 @@ Bool_t MagneticField::loadParameterization() mLogger->Fatal(MESSAGE_ORIGIN, "Failed to open magnetic field data file %s\n", fname); } - mMeasuredMap = dynamic_cast(file->Get(getParameterName())); + mMeasuredMap = std::unique_ptr + (dynamic_cast(file->Get(getParameterName()))); if (!mMeasuredMap) { mLogger->Fatal(MESSAGE_ORIGIN, "Did not find field %s in %s\n", getParameterName(), fname); } @@ -194,7 +225,7 @@ Bool_t MagneticField::loadParameterization() return kTRUE; } -void MagneticField::Field(const Double_t *xyz, Double_t *b) +void MagneticField::GetFieldValue(const Double_t *xyz, Double_t *b) { // b[0]=b[1]=b[2]=0.0; if (mMeasuredMap && xyz[2] > mMeasuredMap->getMinZ() && xyz[2] < mMeasuredMap->getMaxZ()) { @@ -228,10 +259,7 @@ MagneticField &MagneticField::operator=(const MagneticField &src) { if (this != &src) { if (src.mMeasuredMap) { - if (mMeasuredMap) { - delete mMeasuredMap; - } - mMeasuredMap = new MagneticWrapperChebyshev(*src.mMeasuredMap); + mMeasuredMap.reset(new MagneticWrapperChebyshev(*src.getMeasuredMap())); } SetName(src.GetName()); mSolenoid = src.mSolenoid; @@ -573,3 +601,88 @@ void MagneticField::Print(Option_t *opt) const mLogger->Info(MESSAGE_ORIGIN, "Uses %s of %s", getParameterName(), getDataFileName()); } } + +void MagneticField::FillParContainer() +{ + // fill field parameters + FairRun* fRun = FairRun::Instance(); + FairRuntimeDb* rtdb = fRun->GetRuntimeDb(); + MagFieldParam* par = static_cast(rtdb->getContainer("MagFieldParam")); + par->SetParam(this); + par->setChanged(); +} + + +//======================================== +ClassImp(MagFieldParam); + +MagFieldParam::MagFieldParam(const char* name, const char* title, const char* context) + :FairParGenericSet(name, title, context) + ,mMapType(MagneticField::k5kG) + ,mBeamType(MagneticField::kNoBeamField) + ,mDefaultIntegration(0) + ,mFactorSol(0.) + ,mFactorDip(0.) + ,mBeamEnergy(0.) + ,mMaxField(0.) + ,mMapPath() +{ + /// create param for alice mag. field +} + +void MagFieldParam::SetParam(const MagneticField* field) +{ + /// fill parameters from the initialized field + // SetName(field->GetName()); ? is this needed + // SetTitle(field->GetTitle()); + mMapType = field->getMapType(); + mBeamType = field->getBeamType(); + mDefaultIntegration = field->Integral(); + mFactorSol = field->getFactorSolenoid(); + mFactorDip = field->getFactorDipole(); + mBeamEnergy = field->getBeamEnergy(); + mMaxField = field->Max(); + mMapPath = field->getDataFileName(); + // +} + +void MagFieldParam::putParams(FairParamList* list) +{ + /// store parameters in the list + if (!list) return; + list->add("Map Type ID", int(mMapType)); + list->add("Beam Type ID", int(mBeamType)); + list->add("Integral Type", mDefaultIntegration); + list->add("Fact.Solenoid", mFactorSol); + list->add("Fact.Dipole ", mFactorDip); + list->add("Beam Energy ", mBeamEnergy); + list->add("Max. Field ", mMaxField); + list->add("Path to map ", mMapPath.Data()); + // +} + +Bool_t MagFieldParam::getParams(FairParamList* list) +{ + /// retried parameters + int int2enum=0; + if (!list->fill("Map Type ID", &int2enum)) return kFALSE; + mMapType = static_cast(int2enum); + if (!list->fill("Beam Type ID", &int2enum)) return kFALSE; + mBeamType = static_cast(int2enum); + // + if (!list->fill("Integral Type", &mDefaultIntegration)) return kFALSE; + if (!list->fill("Fact.Solenoid", &mFactorSol)) return kFALSE; + if (!list->fill("Fact.Dipole ", &mFactorDip)) return kFALSE; + if (!list->fill("Beam Energy ", &mBeamEnergy)) return kFALSE; + if (!list->fill("Max. Field ", &mMaxField)) return kFALSE; + FairParamObj* parpath = list->find("Path to map "); + if (!parpath) return kFALSE; + int lgt = parpath->getLength(); + // RS: is there a bug in FairParamList::fill(const Text_t* name,Text_t* value,const Int_t length)? + // I think the "if (lfill("Path to map ", cbuff, lgt+2)) return kFALSE; + mMapPath = cbuff; + return kTRUE; +} From a54fd3cd72af3cd5f776e00a691d08cfc1065311 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 23 Jan 2017 15:45:34 +0100 Subject: [PATCH 3/7] missing include added --- Common/Field/include/Field/MagneticField.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Common/Field/include/Field/MagneticField.h b/Common/Field/include/Field/MagneticField.h index 64563b01a85b9..da25957dca60b 100644 --- a/Common/Field/include/Field/MagneticField.h +++ b/Common/Field/include/Field/MagneticField.h @@ -11,6 +11,7 @@ #include "TSystem.h" #include "Rtypes.h" // for Double_t, Char_t, Int_t, Float_t, etc #include "TNamed.h" // for TNamed +#include // for str::unique_ptr class FairLogger; // lines 14-14 class FairParamList; From 697223df58a1a1d835f8571e0aa165f8da0d8d8e Mon Sep 17 00:00:00 2001 From: mkrzewic Date: Thu, 19 Jan 2017 15:17:11 +0100 Subject: [PATCH 4/7] Make buffer access const, received buffers should be unmutable by default --- DataFormats/Headers/include/Headers/DataHeader.h | 12 ++++++------ Utilities/O2device/include/O2device/O2device.h | 11 +++++------ .../include/fairMQmonitor/FairMQmonitor.h | 4 ++-- Utilities/fairMQmonitor/src/FairMQmonitor.cxx | 4 ++-- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/DataFormats/Headers/include/Headers/DataHeader.h b/DataFormats/Headers/include/Headers/DataHeader.h index 23a5b8d42d583..a1ea242001f6e 100644 --- a/DataFormats/Headers/include/Headers/DataHeader.h +++ b/DataFormats/Headers/include/Headers/DataHeader.h @@ -242,9 +242,9 @@ struct BaseHeader /// @brief access header in buffer /// /// this is to guess if the buffer starting at b looks like a header - inline static const BaseHeader* get(byte* b, size_t /*len*/=0) { - return (*(reinterpret_cast(b))==sMagicString) ? - reinterpret_cast(b) : + inline static const BaseHeader* get(const byte* b, size_t /*len*/=0) { + return (*(reinterpret_cast(b))==sMagicString) ? + reinterpret_cast(b) : nullptr; } @@ -264,7 +264,7 @@ struct BaseHeader /// use like this: /// HeaderType* h = get(buffer) template -const HeaderType* get(byte* buffer, size_t /*len*/=0) { +const HeaderType* get(const byte* buffer, size_t /*len*/=0) { const BaseHeader* current = BaseHeader::get(buffer); if (!current) return nullptr; if (current->description==HeaderType::sHeaderType) @@ -304,8 +304,8 @@ struct Block { size_t bufferSize; Buffer buffer; - byte* data() {return buffer.get();} - size_t size() {return bufferSize;} + byte* data() const {return buffer.get();} + size_t size() const {return bufferSize;} ///The magic constructor: takes arbitrary number of arguments and serialized them /// into the buffer. diff --git a/Utilities/O2device/include/O2device/O2device.h b/Utilities/O2device/include/O2device/O2device.h index 0bd5f5a5617dd..d50a1701038f9 100644 --- a/Utilities/O2device/include/O2device/O2device.h +++ b/Utilities/O2device/include/O2device/O2device.h @@ -62,12 +62,11 @@ class O2device : public FairMQDevice /// currently this is old school: buf,len pairs; /// In the end I'd like to move to array_view /// when this becomes available (either with C++17 or via GSL) - template - bool ForEach(O2message& parts, - bool (T::* memberFunction)(byte* headerBuffer, size_t headerBufferSize, - byte* dataBuffer, size_t dataBufferSize)) { - - if ((parts.Size()%2) != 0) + template + bool ForEach(O2message& parts, bool (T::*memberFunction)(const byte* headerBuffer, size_t headerBufferSize, + const byte* dataBuffer, size_t dataBufferSize)) + { + if ((parts.Size() % 2) != 0) throw std::invalid_argument("number of parts in message not even (n%2 != 0)"); for (auto it = parts.fParts.begin(); it != parts.fParts.end(); ++it) { diff --git a/Utilities/fairMQmonitor/include/fairMQmonitor/FairMQmonitor.h b/Utilities/fairMQmonitor/include/fairMQmonitor/FairMQmonitor.h index bc810c7a6ec67..3f2f859207878 100644 --- a/Utilities/fairMQmonitor/include/fairMQmonitor/FairMQmonitor.h +++ b/Utilities/fairMQmonitor/include/fairMQmonitor/FairMQmonitor.h @@ -38,8 +38,8 @@ class FairMQmonitor : public AliceO2::Base::O2device virtual void Run(); void InitTask(); bool HandleData(AliceO2::Base::O2message& parts, int index); - bool HandleO2frame(byte* headerBuffer, size_t headerBufferSize, - byte* dataBuffer, size_t dataBufferSize); + bool HandleO2frame(const byte* headerBuffer, size_t headerBufferSize, + const byte* dataBuffer, size_t dataBufferSize); private: AliceO2::Header::DataHeader mDataHeader; diff --git a/Utilities/fairMQmonitor/src/FairMQmonitor.cxx b/Utilities/fairMQmonitor/src/FairMQmonitor.cxx index 148ab77e6d85f..612b77af59c13 100644 --- a/Utilities/fairMQmonitor/src/FairMQmonitor.cxx +++ b/Utilities/fairMQmonitor/src/FairMQmonitor.cxx @@ -92,8 +92,8 @@ void FairMQmonitor::Run() } //__________________________________________________________________________________________________ -bool FairMQmonitor::HandleO2frame(byte* headerBuffer, size_t headerBufferSize, - byte* dataBuffer, size_t dataBufferSize) +bool FairMQmonitor::HandleO2frame(const byte* headerBuffer, size_t headerBufferSize, + const byte* dataBuffer, size_t dataBufferSize) { hexDump("headerBuffer", headerBuffer, headerBufferSize); From a708da3b0fbe8d941768d0135110768a4974cc8c Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Thu, 19 Jan 2017 23:23:09 +0100 Subject: [PATCH 5/7] Generic initializer methods for string to uint conversions --- .../Headers/include/Headers/DataHeader.h | 104 ++++++++++++------ DataFormats/Headers/src/DataHeader.cxx | 2 +- 2 files changed, 73 insertions(+), 33 deletions(-) diff --git a/DataFormats/Headers/include/Headers/DataHeader.h b/DataFormats/Headers/include/Headers/DataHeader.h index a1ea242001f6e..bf3e79e70315d 100644 --- a/DataFormats/Headers/include/Headers/DataHeader.h +++ b/DataFormats/Headers/include/Headers/DataHeader.h @@ -78,62 +78,102 @@ constexpr uint32_t gSizeHeaderDescriptionString = 8; struct DataHeader; struct DataIdentifier; +//__________________________________________________________________________________________________ +// internal implementation +/// @ingroup aliceo2_dataformat_tools +namespace Internal { +// terminating initializer implementation +template +constexpr T String2__() +{ + return 0; +} +// recursive initializer implementation +template +constexpr T String2__(char c, Targs... Fargs) +{ + return (T) c | String2__(Fargs...) << 8; +} + +/// compile time evaluation of the number of arguments in argument pack +template +struct getnargs { + static int const value = getnargs::value + 1; +}; +template +struct getnargs { + static int const value = 1; +}; +}; + //__________________________________________________________________________________________________ /// constexpr intializer, evaluated at compile time +/// generic intializer for variable char argument list +template +constexpr T String2(char c, Targs... Fargs) +{ + // number of arguments has either to match the size of the type, or the last element is treated + // as '0' if missing + static_assert(Internal::getnargs::value == sizeof(T) || + Internal::getnargs::value == sizeof(T) - 1, + "number of arguments does not match the uint type width" + ); + return Internal::String2__(c, Fargs...); +} + +/// constexpr intializer, evaluated at compile time +/// backward compatibility, might be removed in the future constexpr uint64_t String2uint64(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8) { - return((uint64_t) c1 | (uint64_t) c2 << 8 | (uint64_t) c3 << 16 | (uint64_t) c4 << 24 | - (uint64_t) c5 << 32 | (uint64_t) c6 << 40 | (uint64_t) c7 << 48 | (uint64_t) c8 << 56); + return String2(c1, c2, c3, c4, c5, c6, c7, c8); } /// constexpr intializer, evaluated at compile time -constexpr uint64_t String2uint64(const char* str, int pos=0) +/// generic initializer, convert a string to unsigned integer of different width +/// Example usage: String2("IDENTIFY") +/// @ingroup aliceo2_dataformat_tools +template +constexpr T String2(const char* str, int pos=0) { - return((uint64_t) str[0+pos] | - (str[0+pos] ? ((uint64_t) str[1+pos] << 8 | - (str[1+pos] ? ((uint64_t) str[2+pos] << 16 | - (str[2+pos] ? ((uint64_t) str[3+pos] << 24 | - (str[3+pos] ? ((uint64_t) str[4+pos] << 32 | - (str[4+pos] ? ((uint64_t) str[5+pos] << 40 | - (str[5+pos] ? ((uint64_t) str[6+pos] << 48 | - (str[6+pos] ? ((uint64_t) str[7+pos] << 56 ) + return((T) str[0+pos] | + (str[0+pos] && sizeof(T) >= 2 ? ((T) str[1+pos] << (sizeof(T) >= 2 ? 8 : 0) | + (str[1+pos] && sizeof(T) >= 4 ? ((T) str[2+pos] << (sizeof(T) >= 4 ? 16 : 0) | + (str[2+pos] && sizeof(T) >= 4 ? ((T) str[3+pos] << (sizeof(T) >= 4 ? 24 : 0) | + (str[3+pos] && sizeof(T) >= 8 ? ((T) str[4+pos] << (sizeof(T) >= 8 ? 32 : 0) | + (str[4+pos] && sizeof(T) >= 8 ? ((T) str[5+pos] << (sizeof(T) >= 8 ? 40 : 0) | + (str[5+pos] && sizeof(T) >= 8 ? ((T) str[6+pos] << (sizeof(T) >= 8 ? 48 : 0) | + (str[6+pos] && sizeof(T) >= 8 ? ((T) str[7+pos] << (sizeof(T) >= 8 ? 56 : 0) ) : 0)) : 0)) : 0)) : 0)) : 0)) : 0)) : 0)); } -/// constexpr intializer, evaluated at compile time -constexpr uint32_t String2uint32(char c1, char c2, char c3) +/// backward compatibility, can be removed +/// forwards to generic function +constexpr uint64_t String2uint64(const char* str, int pos=0) { - return((uint32_t) c1 | (uint32_t) c2 << 8 | (uint32_t) c3 << 16); + return String2(str, pos); } -/// constexpr intializer, evaluated at compile time -constexpr uint32_t String2uint32(const char* str) +/// backward compatibility, can be removed +/// forwards to generic function +constexpr uint32_t String2uint32(const char* str, int pos=0) { - return((uint32_t) str[0] | - (str[0] ? ((uint32_t) str[1] << 8 | - (str[1] ? ((uint32_t) str[2] << 16 | - (str[2] ? ((uint32_t) str[3] << 24 ) - :0 )) : 0)) : 0)); + return String2(str, pos); } + /// constexpr intializer, evaluated at compile time -constexpr uint32_t CharArr2uint32(char c1, char c2, char c3, char c4) +/// backward compatibility, might be removed in the future +constexpr uint32_t String2uint32(char c1, char c2, char c3) { - return((uint32_t) c1 | - (uint32_t) c2 << 8 | - (uint32_t) c3 << 16 | - (uint32_t) c4 << 24); + return String2(c1, c2, c3); } /// constexpr intializer, evaluated at compile time -constexpr uint32_t CharArr2uint32(const char* str) +/// backward compatibility, might be removed in the future +constexpr uint32_t CharArr2uint32(char c1, char c2, char c3, char c4) { - return((uint32_t) str[0] | - (str[0] ? ((uint32_t) str[1] << 8 | - (str[1] ? ((uint32_t) str[2] << 16 | - (str[2] ? ((uint32_t) str[3] << 24) - : 0)) : 0)) : 0)); + return String2(c1, c2, c3, c4); } //__________________________________________________________________________________________________ diff --git a/DataFormats/Headers/src/DataHeader.cxx b/DataFormats/Headers/src/DataHeader.cxx index d2c27e5510fd6..f0a0e824534a2 100644 --- a/DataFormats/Headers/src/DataHeader.cxx +++ b/DataFormats/Headers/src/DataHeader.cxx @@ -15,7 +15,7 @@ #include // strncpy //the answer to life and everything -const uint32_t AliceO2::Header::BaseHeader::sMagicString = CharArr2uint32("O2O2"); +const uint32_t AliceO2::Header::BaseHeader::sMagicString = String2("O2O2"); //possible serialization types const AliceO2::Header::SerializationMethod AliceO2::Header::gSerializationMethodAny ("*******"); From 39885739891209ad6ee79044ae6eb5eb3cb35f78 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 20 Jan 2017 01:37:02 +0100 Subject: [PATCH 6/7] Adding generic implemenation for descriptors Implements a generic container for the union of a char and a uint element of the same size. Simple definition of 1 to 8 byte decriptors. The generalization for more than 8 bytes can be activated later once an appropriate test setup is available. --- .../Headers/include/Headers/DataHeader.h | 105 +++++++++++++++--- DataFormats/Headers/src/DataHeader.cxx | 11 +- 2 files changed, 88 insertions(+), 28 deletions(-) diff --git a/DataFormats/Headers/include/Headers/DataHeader.h b/DataFormats/Headers/include/Headers/DataHeader.h index bf3e79e70315d..a9d5795bf6d7c 100644 --- a/DataFormats/Headers/include/Headers/DataHeader.h +++ b/DataFormats/Headers/include/Headers/DataHeader.h @@ -79,7 +79,7 @@ struct DataHeader; struct DataIdentifier; //__________________________________________________________________________________________________ -// internal implementation +// internal implementations /// @ingroup aliceo2_dataformat_tools namespace Internal { // terminating initializer implementation @@ -104,6 +104,50 @@ template struct getnargs { static int const value = 1; }; + +/// get the number of active bits (set to 1) in a bitfield +template +struct NumberOfActiveBits { + static int const value = NumberOfActiveBits<(N >> 1)>::value + (N & 0x1); +}; +template <> +struct NumberOfActiveBits<0> { + static int const value = 0; +}; + +/// evaluate the array size necessary to hold a N-byte number with type T + template +struct ArraySize { + static_assert(N >= sizeof(T), "get this code to work first"); + static int const value = 1; + //static int const value = std::conditional<(N > sizeof(T)), ArraySize<(N - sizeof(T)), T>, ArraySize<0, T>>::value + 1; +}; +template +struct ArraySize<0, T> { + static int const value = 0; +}; + +/// select uint type depending on size, default is uint64_t +template +struct TraitsIntType { + typedef uint64_t type; +}; +template <> +struct TraitsIntType<1> { + typedef uint8_t type; +}; +template <> +struct TraitsIntType<2> { + typedef uint16_t type; +}; +template <> +struct TraitsIntType<4> { + typedef uint32_t type; +}; + +struct defaultPrinter { + void operator()(const char* str) const {} +}; }; //__________________________________________________________________________________________________ @@ -176,6 +220,45 @@ constexpr uint32_t CharArr2uint32(char c1, char c2, char c3, char c4) return String2(c1, c2, c3, c4); } +//__________________________________________________________________________________________________ +/// generic descriptor class faturing the union of a char and a uint element +/// of the same size +/// this is currently working only for up to 8 bytes aka uint64_t, the general +/// solution is working also for multiples of 64 bit, but then the itg member needs +/// to be an array for all. This has not been enabled yet, first the implications +/// have to be studied. +template +struct Descriptor { + static_assert(Internal::NumberOfActiveBits::value == 1 && N <= 8, + "size is required to be 1 or a multiple of 2"); + static int const size = N; + static int const bitcount = size*8; + static int const arraySize = 1; //Internal::ArraySize::value; + typedef typename Internal::TraitsIntType::type ItgType; + + union { + char str[N]; + ItgType itg; // for extension > 64 bit: [arraySize]; + }; + Descriptor() {}; + Descriptor(const Descriptor& other) : itg(other.itg) {} + Descriptor& operator=(const Descriptor& other) { + if (&other != this) itg = other.itg; + return *this; + } + // note: no operator=(const char*) as this potentially runs into trouble with this + // general pointer type, use: somedescriptor = Descriptor("DESCRIPTION") + constexpr Descriptor(const char* origin) : itg(String2(origin)) {}; + bool operator==(const Descriptor& other) const {return itg == other.itg;} + bool operator!=(const Descriptor& other) const {return not this->operator==(other);} + // print function needs to be implemented for every derivation + PrinterPolicy printer; + void print() const { + // eventually terminate string before printing + printer(str); + }; +}; + //__________________________________________________________________________________________________ /// default int representation of 'invalid' token for 4-byte char field const uint32_t gInvalidToken32 = 0xFFFFFFFF; @@ -479,24 +562,10 @@ struct DataDescription { //__________________________________________________________________________________________________ // 32bit (4 characters) for data origin, ex. the detector or subsystem name -struct DataOrigin { - union { - char str[gSizeDataOriginString]; - uint32_t itg; - }; - DataOrigin(); - DataOrigin(const DataOrigin& other) : itg(other.itg) {} - DataOrigin& operator=(const DataOrigin& other) { - if (&other != this) itg = other.itg; - return *this; - } - // note: no operator=(const char*) as this potentially runs into trouble with this - // general pointer type, use: someorigin = DataOrigin("BLA") - constexpr DataOrigin(const char* origin) : itg{String2uint32(origin)} {}; - bool operator==(const DataOrigin&) const; - bool operator!=(const DataOrigin& other) const {return not this->operator==(other);} - void print() const; +struct printDataOrigin { + void operator()(const char* str) const; }; +typedef Descriptor DataOrigin; //__________________________________________________________________________________________________ /// @struct DataHeader diff --git a/DataFormats/Headers/src/DataHeader.cxx b/DataFormats/Headers/src/DataHeader.cxx index f0a0e824534a2..d4481066d6eda 100644 --- a/DataFormats/Headers/src/DataHeader.cxx +++ b/DataFormats/Headers/src/DataHeader.cxx @@ -176,16 +176,7 @@ bool AliceO2::Header::DataHeader::operator==(const DataHeader& that) const } //__________________________________________________________________________________________________ -AliceO2::Header::DataOrigin::DataOrigin() : itg(gInvalidToken32) {} - -//__________________________________________________________________________________________________ -bool AliceO2::Header::DataOrigin::operator==(const DataOrigin& other) const -{ - return itg == other.itg; -} - -//__________________________________________________________________________________________________ -void AliceO2::Header::DataOrigin::print() const +void AliceO2::Header::printDataOrigin::operator()(const char* str) const { printf("Data origin : %s\n", str); } From 763deda4ff99eb0ee5a57074ce971581d54afc63 Mon Sep 17 00:00:00 2001 From: shahoian Date: Mon, 6 Feb 2017 19:16:29 +0100 Subject: [PATCH 7/7] Moved field/beam types to MagFieldParam and extracted it to separate module --- Common/Field/CMakeLists.txt | 2 + Common/Field/include/Field/MagFieldParam.h | 62 +++++++++ Common/Field/include/Field/MagneticField.h | 65 ++-------- Common/Field/src/MagFieldParam.cxx | 86 +++++++++++++ Common/Field/src/MagneticField.cxx | 139 +++++---------------- 5 files changed, 196 insertions(+), 158 deletions(-) create mode 100644 Common/Field/include/Field/MagFieldParam.h create mode 100644 Common/Field/src/MagFieldParam.cxx diff --git a/Common/Field/CMakeLists.txt b/Common/Field/CMakeLists.txt index b39c6e0083ce7..e8714d613dc68 100644 --- a/Common/Field/CMakeLists.txt +++ b/Common/Field/CMakeLists.txt @@ -4,12 +4,14 @@ O2_SETUP(NAME ${MODULE_NAME}) set(SRCS src/MagneticWrapperChebyshev.cxx + src/MagFieldParam.cxx src/MagneticField.cxx ) set(HEADERS include/${MODULE_NAME}/MagneticWrapperChebyshev.h include/${MODULE_NAME}/MagneticField.h + include/${MODULE_NAME}/MagFieldParam.h ) set(LINKDEF src/FieldLinkDef.h) set(LIBRARY_NAME ${MODULE_NAME}) diff --git a/Common/Field/include/Field/MagFieldParam.h b/Common/Field/include/Field/MagFieldParam.h new file mode 100644 index 0000000000000..b0d3dc4e98d86 --- /dev/null +++ b/Common/Field/include/Field/MagFieldParam.h @@ -0,0 +1,62 @@ +/// \file MagFieldParam.h +/// \brief Definition of the MagFieldParam: container for ALICE mag. field parameters +/// \author ruben.shahoyan@cern.ch + +#ifndef ALICEO2_FIELD_MAGFIELDPARAM_H_ +#define ALICEO2_FIELD_MAGFIELDPARAM_H_ + +#include "FairParGenericSet.h" +#include + +class FairParamList; + + +namespace AliceO2 { + namespace Field { + +class MagneticField; + +class MagFieldParam : public FairParGenericSet +{ + public: + enum BMap_t + { + k2kG, k5kG, k5kGUniform + }; + enum BeamType_t + { + kNoBeamField, kBeamTypepp, kBeamTypeAA, kBeamTypepA, kBeamTypeAp + }; + + MagFieldParam(const char* name="", const char* title="", const char* context=""); + + void SetParam(const MagneticField* field); + + BMap_t GetMapType() const {return mMapType;} + BeamType_t GetBeamType() const {return mBeamType;} + Int_t GetDefInt() const {return mDefaultIntegration;} + Double_t GetFactorSol() const {return mFactorSol;} + Double_t GetFactorDip() const {return mFactorDip;} + Double_t GetBeamEnergy() const {return mBeamEnergy;} + Double_t GetMaxField() const {return mMaxField;} + const char* GetMapPath() const {return mMapPath.Data();} + + virtual void putParams(FairParamList* list); + virtual Bool_t getParams(FairParamList* list); + + protected: + BMap_t mMapType; ///< map type ID + BeamType_t mBeamType; ///< beam type ID + Int_t mDefaultIntegration; ///< field integration type for MC + Double_t mFactorSol; ///< solenoid current factor + Double_t mFactorDip; ///< dipole current factor + Double_t mBeamEnergy; ///< beam energy + Double_t mMaxField; ///< max field for geant + TString mMapPath; ///< path to map file + + ClassDef(MagFieldParam,1) +}; +} +} + +#endif diff --git a/Common/Field/include/Field/MagneticField.h b/Common/Field/include/Field/MagneticField.h index da25957dca60b..e9729ddacfd73 100644 --- a/Common/Field/include/Field/MagneticField.h +++ b/Common/Field/include/Field/MagneticField.h @@ -6,7 +6,7 @@ #define ALICEO2_FIELD_MAGNETICFIELD_H_ #include "FairField.h" // for FairField -#include "FairParGenericSet.h" +#include "Field/MagFieldParam.h" #include "Field/MagneticWrapperChebyshev.h" // for MagneticWrapperChebyshev #include "TSystem.h" #include "Rtypes.h" // for Double_t, Char_t, Int_t, Float_t, etc @@ -20,7 +20,6 @@ namespace AliceO2 { namespace Field { class MagneticWrapperChebyshev; }} // lin namespace AliceO2 { namespace Field { -class MagFieldParam; class MagneticWrapperChebyshev; /// Interface between the TVirtualMagField and MagneticWrapperChebyshev: wrapper to the set of magnetic field data + @@ -30,14 +29,6 @@ class MagneticField : public FairField { public: - enum BMap_t - { - k2kG, k5kG, k5kGUniform - }; - enum BeamType_t - { - kNoBeamField, kBeamTypepp, kBeamTypeAA, kBeamTypepA, kBeamTypeAp - }; enum PolarityConvention_t { kConvLHC, kConvDCS2008, kConvMap2005 @@ -54,7 +45,9 @@ class MagneticField : public FairField /// Impose scaling of parameterized L3 field by factorSol and of dipole by factorDip. /// The "be" is the energy of the beam in GeV/nucleon MagneticField(const char *name, const char *title, Double_t factorSol = 1., Double_t factorDip = 1., - BMap_t maptype = k5kG, BeamType_t btype = kBeamTypepp, Double_t benergy = -1, Int_t integ = 2, + MagFieldParam::BMap_t maptype = MagFieldParam::k5kG, + MagFieldParam::BeamType_t btype = MagFieldParam::kBeamTypepp, + Double_t benergy = -1, Int_t integ = 2, Double_t fmax = 15, const std::string path = std::string(gSystem->Getenv("VMCWORKDIR")) + std::string("/Common/maps/mfchebKGI_sym.root") ); @@ -140,7 +133,7 @@ class MagneticField : public FairField Double_t getCurrentSolenoid() const { - return getFactorSolenoid() * (mMapType == k2kG ? 12000 : 30000); + return getFactorSolenoid() * (mMapType == MagFieldParam::k2kG ? 12000 : 30000); } Double_t getCurrentDipole() const @@ -150,17 +143,17 @@ class MagneticField : public FairField Bool_t IsUniform() const { - return mMapType == k5kGUniform; + return mMapType == MagFieldParam::k5kGUniform; } void MachineField(const Double_t *x, Double_t *b) const; - BMap_t getMapType() const + MagFieldParam::BMap_t getMapType() const { return mMapType; } - BeamType_t getBeamType() const + MagFieldParam::BeamType_t getBeamType() const { return mBeamType; } @@ -237,9 +230,9 @@ class MagneticField : public FairField protected: // not supposed to be changed during the run, set only at the initialization via constructor - void initializeMachineField(BeamType_t btype, Double_t benergy); + void initializeMachineField(MagFieldParam::BeamType_t btype, Double_t benergy); - void setBeamType(BeamType_t type) + void setBeamType(MagFieldParam::BeamType_t type) { mBeamType = type; } @@ -251,9 +244,9 @@ class MagneticField : public FairField protected: std::unique_ptr mMeasuredMap; //! Measured part of the field map - BMap_t mMapType; ///< field map type + MagFieldParam::BMap_t mMapType; ///< field map type Double_t mSolenoid; ///< Solenoid field setting - BeamType_t mBeamType; ///< Beam type: A-A (mBeamType=0) or p-p (mBeamType=1) + MagFieldParam::BeamType_t mBeamType; ///< Beam type: A-A (mBeamType=0) or p-p (mBeamType=1) Double_t mBeamEnergy; ///< Beam energy in GeV Int_t mDefaultIntegration; ///< Default integration method as indicated in Geant @@ -282,39 +275,7 @@ class MagneticField : public FairField ClassDef(AliceO2::Field::MagneticField, - 2) // Class for all Alice MagField wrapper for measured data + Tosca parameterization -}; - -class MagFieldParam : public FairParGenericSet -{ - public: - MagFieldParam(const char* name="", const char* title="", const char* context=""); - - void SetParam(const MagneticField* field); - - MagneticField::BMap_t GetMapType() const {return mMapType;} - MagneticField::BeamType_t GetBeamType() const {return mBeamType;} - Int_t GetDefInt() const {return mDefaultIntegration;} - Double_t GetFactorSol() const {return mFactorSol;} - Double_t GetFactorDip() const {return mFactorDip;} - Double_t GetBeamEnergy() const {return mBeamEnergy;} - Double_t GetMaxField() const {return mMaxField;} - const char* GetMapPath() const {return mMapPath.Data();} - - virtual void putParams(FairParamList* list); - virtual Bool_t getParams(FairParamList* list); - - protected: - MagneticField::BMap_t mMapType; ///< map type ID - MagneticField::BeamType_t mBeamType; ///< beam type ID - Int_t mDefaultIntegration; ///< field integration type for MC - Double_t mFactorSol; ///< solenoid current factor - Double_t mFactorDip; ///< dipole current factor - Double_t mBeamEnergy; ///< beam energy - Double_t mMaxField; ///< max field for geant - TString mMapPath; ///< path to map file - - ClassDef(MagFieldParam,1) + 3) // Class for all Alice MagField wrapper for measured data + Tosca parameterization }; } } diff --git a/Common/Field/src/MagFieldParam.cxx b/Common/Field/src/MagFieldParam.cxx new file mode 100644 index 0000000000000..7d7394c0a08f9 --- /dev/null +++ b/Common/Field/src/MagFieldParam.cxx @@ -0,0 +1,86 @@ +/// \file MagFieldParam.cxx +/// \brief Implementation of the MagFieldParam class +/// \author ruben.shahoyan@cern.ch + +#include "Field/MagFieldParam.h" +#include "Field/MagneticField.h" +#include "FairParamList.h" +#include "FairRun.h" +#include "FairRuntimeDb.h" + +using namespace AliceO2::Field; + + +//======================================== +ClassImp(MagFieldParam); + +MagFieldParam::MagFieldParam(const char* name, const char* title, const char* context) + :FairParGenericSet(name, title, context) + ,mMapType(k5kG) + ,mBeamType(kNoBeamField) + ,mDefaultIntegration(0) + ,mFactorSol(0.) + ,mFactorDip(0.) + ,mBeamEnergy(0.) + ,mMaxField(0.) + ,mMapPath() +{ + /// create param for alice mag. field +} + +void MagFieldParam::SetParam(const MagneticField* field) +{ + /// fill parameters from the initialized field + // SetName(field->GetName()); ? is this needed + // SetTitle(field->GetTitle()); + mMapType = field->getMapType(); + mBeamType = field->getBeamType(); + mDefaultIntegration = field->Integral(); + mFactorSol = field->getFactorSolenoid(); + mFactorDip = field->getFactorDipole(); + mBeamEnergy = field->getBeamEnergy(); + mMaxField = field->Max(); + mMapPath = field->getDataFileName(); + // +} + +void MagFieldParam::putParams(FairParamList* list) +{ + /// store parameters in the list + if (!list) return; + list->add("Map Type ID", int(mMapType)); + list->add("Beam Type ID", int(mBeamType)); + list->add("Integral Type", mDefaultIntegration); + list->add("Fact.Solenoid", mFactorSol); + list->add("Fact.Dipole ", mFactorDip); + list->add("Beam Energy ", mBeamEnergy); + list->add("Max. Field ", mMaxField); + list->add("Path to map ", mMapPath.Data()); + // +} + +Bool_t MagFieldParam::getParams(FairParamList* list) +{ + /// retried parameters + int int2enum=0; + if (!list->fill("Map Type ID", &int2enum)) return kFALSE; + mMapType = static_cast(int2enum); + if (!list->fill("Beam Type ID", &int2enum)) return kFALSE; + mBeamType = static_cast(int2enum); + // + if (!list->fill("Integral Type", &mDefaultIntegration)) return kFALSE; + if (!list->fill("Fact.Solenoid", &mFactorSol)) return kFALSE; + if (!list->fill("Fact.Dipole ", &mFactorDip)) return kFALSE; + if (!list->fill("Beam Energy ", &mBeamEnergy)) return kFALSE; + if (!list->fill("Max. Field ", &mMaxField)) return kFALSE; + FairParamObj* parpath = list->find("Path to map "); + if (!parpath) return kFALSE; + int lgt = parpath->getLength(); + // RS: is there a bug in FairParamList::fill(const Text_t* name,Text_t* value,const Int_t length)? + // I think the "if (lfill("Path to map ", cbuff, lgt+2)) return kFALSE; + mMapPath = cbuff; + return kTRUE; +} diff --git a/Common/Field/src/MagneticField.cxx b/Common/Field/src/MagneticField.cxx index a75b23d6a9353..b6ce37e8c80b4 100644 --- a/Common/Field/src/MagneticField.cxx +++ b/Common/Field/src/MagneticField.cxx @@ -55,9 +55,9 @@ const UShort_t MagneticField::sPolarityConvention = MagneticField::kConvLHC; MagneticField::MagneticField() : FairField(), mMeasuredMap(nullptr), - mMapType(k5kG), + mMapType(MagFieldParam::k5kG), mSolenoid(0), - mBeamType(kNoBeamField), + mBeamType(MagFieldParam::kNoBeamField), mBeamEnergy(0), mDefaultIntegration(0), mPrecisionInteg(0), @@ -77,8 +77,8 @@ MagneticField::MagneticField() } MagneticField::MagneticField(const char *name, const char *title, Double_t factorSol, Double_t factorDip, - BMap_t maptype, BeamType_t bt, Double_t be, Int_t integ, Double_t fmax, - const std::string path) + MagFieldParam::BMap_t maptype, MagFieldParam::BeamType_t bt, + Double_t be, Int_t integ, Double_t fmax,const std::string path) : FairField(name,title), mMeasuredMap(nullptr), mMapType(maptype), @@ -140,10 +140,10 @@ void MagneticField::CreateField() } if (mDefaultIntegration == 0) mPrecisionInteg = 0; - if (mBeamEnergy <= 0 && mBeamType != kNoBeamField) { - if (mBeamType == kBeamTypepp) mBeamEnergy = 7000.; // max proton energy - else if (mBeamType == kBeamTypeAA) mBeamEnergy = 2760; // max PbPb energy - else if (mBeamType == kBeamTypepA || mBeamType == kBeamTypeAp) + if (mBeamEnergy <= 0 && mBeamType != MagFieldParam::kNoBeamField) { + if (mBeamType == MagFieldParam::kBeamTypepp) mBeamEnergy = 7000.; // max proton energy + else if (mBeamType == MagFieldParam::kBeamTypeAA) mBeamEnergy = 2760; // max PbPb energy + else if (mBeamType == MagFieldParam::kBeamTypepA || mBeamType == MagFieldParam::kBeamTypeAp) mBeamEnergy = 2760; // same rigitiy max PbPb energy // FairLogger::GetLogger()->Info(MESSAGE_ORIGIN, "Maximim possible beam energy for requested beam is assumed"); @@ -151,11 +151,11 @@ void MagneticField::CreateField() const char *parname = 0; - if (mMapType == k2kG) { + if (mMapType == MagFieldParam::k2kG) { parname = mDipoleOnOffFlag ? "Sol12_Dip0_Hole" : "Sol12_Dip6_Hole"; - } else if (mMapType == k5kG) { + } else if (mMapType == MagFieldParam::k5kG) { parname = mDipoleOnOffFlag ? "Sol30_Dip0_Hole" : "Sol30_Dip6_Hole"; - } else if (mMapType == k5kGUniform) { + } else if (mMapType == MagFieldParam::k5kGUniform) { parname = "Sol30_Dip6_Uniform"; } else { mLogger->Fatal(MESSAGE_ORIGIN, "Unknown field identifier %d is requested\n", mMapType); @@ -276,16 +276,16 @@ MagneticField &MagneticField::operator=(const MagneticField &src) return *this; } -void MagneticField::initializeMachineField(BeamType_t btype, Double_t benergy) +void MagneticField::initializeMachineField(MagFieldParam::BeamType_t btype, Double_t benergy) { - if (btype == kNoBeamField) { + if (btype == MagFieldParam::kNoBeamField) { mQuadrupoleGradient = mDipoleField = mCompensatorField2C = mCompensatorField1A = mCompensatorField2A = 0.; return; } double rigScale = benergy / 7000.; // scale according to ratio of E/Enominal // for ions assume PbPb (with energy provided per nucleon) and account for A/Z - if (btype == kBeamTypeAA /* || btype==kBeamTypepA || btype==kBeamTypeAp */) { + if (btype == MagFieldParam::kBeamTypeAA /* || btype==kBeamTypepA || btype==kBeamTypeAp */) { rigScale *= 208. / 82.; } // Attention: in p-Pb the energy recorded in the GRP is the PROTON energy, no rigidity @@ -483,7 +483,7 @@ MagneticField *MagneticField::createFieldMap(Float_t l3Cur, Float_t diCur, Int_t const Float_t tolerance = 0.03; // relative current tolerance const Float_t zero = 77.f; // "zero" current (A) - BMap_t map = k5kG; + MagFieldParam::BMap_t map = MagFieldParam::k5kG; double sclL3, sclDip; Float_t l3Pol = l3Cur > 0 ? 1 : -1; @@ -503,23 +503,23 @@ MagneticField *MagneticField::createFieldMap(Float_t l3Cur, Float_t diCur, Int_t if (uniform) { // special treatment of special MC with uniform mag field (normalized to 0.5 T) // no check for scaling/polarities are done - map = k5kGUniform; + map = MagFieldParam::k5kGUniform; sclL3 = l3Cur / l3NominalCurrent1; } else { if (TMath::Abs((sclL3 = l3Cur / l3NominalCurrent1) - 1.) < tolerance) { - map = k5kG; + map = MagFieldParam::k5kG; } else if (TMath::Abs((sclL3 = l3Cur / l3NominalCurrent2) - 1.) < tolerance) { - map = k2kG; + map = MagFieldParam::k2kG; } else if (l3Cur <= zero && diCur <= zero) { sclL3 = 0; sclDip = 0; - map = k5kGUniform; + map = MagFieldParam::k5kGUniform; } else { FairLogger::GetLogger()->Fatal(MESSAGE_ORIGIN, "Wrong L3 current (%f A)!", l3Cur); } } - if (sclDip != 0 && map != k5kGUniform) { + if (sclDip != 0 && map != MagFieldParam::k5kGUniform) { if ((l3Cur <= zero) || ((convention == kConvLHC && l3Pol != diPol) || (convention == kConvDCS2008 && l3Pol == diPol))) { FairLogger::GetLogger()->Fatal(MESSAGE_ORIGIN, @@ -535,7 +535,7 @@ MagneticField *MagneticField::createFieldMap(Float_t l3Cur, Float_t diCur, Int_t sclDip = -sclDip; } - BeamType_t btype = kNoBeamField; + MagFieldParam::BeamType_t btype = MagFieldParam::kNoBeamField; TString btypestr = beamtype; btypestr.ToLower(); TPRegexp protonBeam("(proton|p)\\s*-?\\s*\\1"); @@ -543,13 +543,13 @@ MagneticField *MagneticField::createFieldMap(Float_t l3Cur, Float_t diCur, Int_t TPRegexp protonionBeam("(proton|p)\\s*-?\\s*(lead|pb|ion|a|A)"); TPRegexp ionprotonBeam("(lead|pb|ion|a|A)\\s*-?\\s*(proton|p)"); if (btypestr.Contains(ionBeam)) { - btype = kBeamTypeAA; + btype = MagFieldParam::kBeamTypeAA; } else if (btypestr.Contains(protonBeam)) { - btype = kBeamTypepp; + btype = MagFieldParam::kBeamTypepp; } else if (btypestr.Contains(protonionBeam)) { - btype = kBeamTypepA; + btype = MagFieldParam::kBeamTypepA; } else if (btypestr.Contains(ionprotonBeam)) { - btype = kBeamTypeAp; + btype = MagFieldParam::kBeamTypeAp; } else { FairLogger::GetLogger()->Info(MESSAGE_ORIGIN, "Assume no LHC magnet field for the beam type %s,", beamtype); } @@ -573,15 +573,15 @@ const char *MagneticField::getBeamTypeText() const const char *beamPPb = "p-A"; const char *beamPbP = "A-p"; switch (mBeamType) { - case kBeamTypepp: + case MagFieldParam::kBeamTypepp: return beamPP; - case kBeamTypeAA: + case MagFieldParam::kBeamTypeAA: return beamPbPb; - case kBeamTypepA: + case MagFieldParam::kBeamTypepA: return beamPPb; - case kBeamTypeAp: + case MagFieldParam::kBeamTypeAp: return beamPbP; - case kNoBeamField: + case MagFieldParam::kNoBeamField: default: return beamNA; } @@ -593,8 +593,9 @@ void MagneticField::Print(Option_t *opt) const opts.ToLower(); mLogger->Info(MESSAGE_ORIGIN, "%s:%s", GetName(), GetTitle()); mLogger->Info(MESSAGE_ORIGIN, "Solenoid (%+.2f*)%.0f kG, Dipole %s (%+.2f) %s", getFactorSolenoid(), - (mMapType == k5kG || mMapType == k5kGUniform) ? 5. : 2., mDipoleOnOffFlag ? "OFF" : "ON", - getFactorDipole(), mMapType == k5kGUniform ? " |Constant Field!" : ""); + (mMapType == MagFieldParam::k5kG || mMapType == MagFieldParam::k5kGUniform) ? 5. : 2., + mDipoleOnOffFlag ? "OFF" : "ON", + getFactorDipole(), mMapType == MagFieldParam::k5kGUniform ? " |Constant Field!" : ""); if (opts.Contains("a")) { mLogger->Info(MESSAGE_ORIGIN, "Machine B fields for %s beam (%.0f GeV): QGrad: %.4f Dipole: %.4f", getBeamTypeText(), mBeamEnergy, mQuadrupoleGradient, mDipoleField); @@ -612,77 +613,3 @@ void MagneticField::FillParContainer() par->setChanged(); } - -//======================================== -ClassImp(MagFieldParam); - -MagFieldParam::MagFieldParam(const char* name, const char* title, const char* context) - :FairParGenericSet(name, title, context) - ,mMapType(MagneticField::k5kG) - ,mBeamType(MagneticField::kNoBeamField) - ,mDefaultIntegration(0) - ,mFactorSol(0.) - ,mFactorDip(0.) - ,mBeamEnergy(0.) - ,mMaxField(0.) - ,mMapPath() -{ - /// create param for alice mag. field -} - -void MagFieldParam::SetParam(const MagneticField* field) -{ - /// fill parameters from the initialized field - // SetName(field->GetName()); ? is this needed - // SetTitle(field->GetTitle()); - mMapType = field->getMapType(); - mBeamType = field->getBeamType(); - mDefaultIntegration = field->Integral(); - mFactorSol = field->getFactorSolenoid(); - mFactorDip = field->getFactorDipole(); - mBeamEnergy = field->getBeamEnergy(); - mMaxField = field->Max(); - mMapPath = field->getDataFileName(); - // -} - -void MagFieldParam::putParams(FairParamList* list) -{ - /// store parameters in the list - if (!list) return; - list->add("Map Type ID", int(mMapType)); - list->add("Beam Type ID", int(mBeamType)); - list->add("Integral Type", mDefaultIntegration); - list->add("Fact.Solenoid", mFactorSol); - list->add("Fact.Dipole ", mFactorDip); - list->add("Beam Energy ", mBeamEnergy); - list->add("Max. Field ", mMaxField); - list->add("Path to map ", mMapPath.Data()); - // -} - -Bool_t MagFieldParam::getParams(FairParamList* list) -{ - /// retried parameters - int int2enum=0; - if (!list->fill("Map Type ID", &int2enum)) return kFALSE; - mMapType = static_cast(int2enum); - if (!list->fill("Beam Type ID", &int2enum)) return kFALSE; - mBeamType = static_cast(int2enum); - // - if (!list->fill("Integral Type", &mDefaultIntegration)) return kFALSE; - if (!list->fill("Fact.Solenoid", &mFactorSol)) return kFALSE; - if (!list->fill("Fact.Dipole ", &mFactorDip)) return kFALSE; - if (!list->fill("Beam Energy ", &mBeamEnergy)) return kFALSE; - if (!list->fill("Max. Field ", &mMaxField)) return kFALSE; - FairParamObj* parpath = list->find("Path to map "); - if (!parpath) return kFALSE; - int lgt = parpath->getLength(); - // RS: is there a bug in FairParamList::fill(const Text_t* name,Text_t* value,const Int_t length)? - // I think the "if (lfill("Path to map ", cbuff, lgt+2)) return kFALSE; - mMapPath = cbuff; - return kTRUE; -}