diff --git a/file/loadinstr.h b/file/loadinstr.h index e4d08431f39676da1c0825298f720a8b0ff81a19..43b15ebba645774a4bec1924083457895f4f6df2 100644 --- a/file/loadinstr.h +++ b/file/loadinstr.h @@ -85,7 +85,9 @@ class FileInstrBase virtual std::size_t NumPolChannels() const; virtual const std::vector>& GetPolStates() const; virtual void SetPolNames(const char* pVec1, const char* pVec2, - const char* pCur1, const char* pCur2); + const char* pCur1, const char* pCur2); // spherical PA + virtual void SetLinPolNames(const char* pFlip1, const char* pFlip2, + const char* pXYZ); // linear PA public: virtual bool MatchColumn(const std::string& strRegex, @@ -125,6 +127,9 @@ class FilePsi : public FileInstrBase<_t_real> std::string m_strPolVec1 {"p1"}, m_strPolVec2 {"p2"}; std::string m_strPolCur1 {"i1"}, m_strPolCur2 {"i2"}; + std::string m_strXYZ {"hx"}; + std::string m_strFlip1 {"f1"}, m_strFlip2 {"f2"}; + protected: void ReadData(std::istream& istr); @@ -201,6 +206,13 @@ class FilePsi : public FileInstrBase<_t_real> m_strPolVec1 = pVec1; m_strPolVec2 = pVec2; m_strPolCur1 = pCur1; m_strPolCur2 = pCur2; } + + virtual void SetLinPolNames(const char* pFlip1, const char* pFlip2, + const char* pXYZ) override + { + m_strFlip1 = pFlip1; m_strFlip2 = pFlip2; + m_strXYZ = pXYZ; + } }; diff --git a/file/loadinstr_impl.h b/file/loadinstr_impl.h index 1d0e23209f58a03ef98c45267f93513d6bbfa71a..308cac8c014cf600675633fcdeea220d9adc7051 100644 --- a/file/loadinstr_impl.h +++ b/file/loadinstr_impl.h @@ -298,6 +298,11 @@ void FileInstrBase::SetPolNames(const char* pVec1, const char* pVec2, const char* pCur1, const char* pCur2) {} +template +void FileInstrBase::SetLinPolNames(const char* pFlip1, const char* pFlip2, + const char* pXYZ) +{} + template std::size_t FileInstrBase::NumPolChannels() const { return 0; } @@ -418,6 +423,8 @@ void FilePsi::ParsePolData() return true; }; + bool bIsSphericalPA = 1; + bool bSwitchOn = 0; // iterate command lines for(std::string& strLine : vecLines) @@ -431,11 +438,14 @@ void FilePsi::ParsePolData() if(vecLine.size() == 0) continue; - if(vecLine[0] == "dr") // polarisation vector or current driven + // first token: dr command + // polarisation vector or current driven + if(vecLine[0] == "dr") { std::string strCurDev = ""; - std::size_t iCurComp = 0; + + // scan next tokens in drive command for(std::size_t iDr=1; iDr::ParsePolData() { t_real dNum = tl::str_to_var(strWord); + // -------------------------------------------------- + // for spherical polarisation analysis + // -------------------------------------------------- if(strCurDev == m_strPolVec1) - { // incoming polarisation vector changed + { + // incoming polarisation vector changed switch(iCurComp) { case 0: Pix = dNum; break; @@ -482,18 +496,84 @@ void FilePsi::ParsePolData() Pf_sign = t_real(-1); } } + // -------------------------------------------------- + + // -------------------------------------------------- + // for linear polarisation analysis + // -------------------------------------------------- + else if(strCurDev == m_strXYZ) + { + bIsSphericalPA = 0; + + // sample guide field vector changed + switch(iCurComp) + { + case 0: Pfx = Pix = dNum; break; + case 1: Pfy = Piy = dNum; break; + case 2: Pfz = Piz = dNum; break; + } + } + // -------------------------------------------------- ++iCurComp; } else // (next) device to drive { - strCurDev = strWord; iCurComp = 0; + strCurDev = strWord; } } } - else if(vecLine[0] == "co") // count command issued -> save current spin states + // -------------------------------------------------- + // for linear polarisation analysis + // -------------------------------------------------- + else if(vecLine.size()>1 && (vecLine[0] == "on" || vecLine[0] == "off" || vecLine[0] == "of")) { + if(vecLine[0] == "on") + bSwitchOn = 1; + else if(vecLine[0] == "off" || vecLine[0] == "of") + bSwitchOn = 0; + + std::string strFlip = vecLine[1]; + + if(strFlip == m_strFlip1) + { + bIsSphericalPA = 0; + Pi_sign = bSwitchOn ? t_real(-1) : t_real(1); + } + else if(strFlip == m_strFlip2) + { + bIsSphericalPA = 0; + Pf_sign = bSwitchOn ? t_real(-1) : t_real(1); + } + } + // -------------------------------------------------- + + + // count command issued -> save current spin states + else if(vecLine[0] == "co") + { + // for linear PA, we only have principal directions + // and diagonal elements of the P matrix + // values in the other components are correction currents + if(!bIsSphericalPA) + { + int maxComp = 0; + if(std::abs(Piy) > std::abs(Pix) && std::abs(Piy) > std::abs(Piz)) + maxComp = 1; + if(std::abs(Piz) > std::abs(Piy) && std::abs(Piz) > std::abs(Pix)) + maxComp = 2; + + Pix = Piy = Piz = Pfx = Pfy = Pfz = 0; + if(maxComp == 0) + Pix = Pfx = 1; + else if(maxComp == 1) + Piy = Pfy = 1; + else if(maxComp == 2) + Piz = Pfz = 1; + } + + m_vecPolStates.push_back(std::array({{ Pi_sign*Pix, Pi_sign*Piy, Pi_sign*Piz, Pf_sign*Pfx, Pf_sign*Pfy, Pf_sign*Pfz }}));