nmrspectrumsolver.cpp
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #include "nmrspectrumsolver.h"
15 #include "ar.h"
16 #ifdef USE_FREQ_ESTM
17  #include "freqest.h"
18 #endif
19 #include "freqestleastsquare.h"
20 
21 const char SpectrumSolverWrapper::SPECTRUM_SOLVER_ZF_FFT[] = "ZF-FFT";
22 const char SpectrumSolverWrapper::SPECTRUM_SOLVER_MEM_STRICT[] = "Strict MEM";
23 const char SpectrumSolverWrapper::SPECTRUM_SOLVER_MEM_STRICT_BURG[] = "Burg+Strict MEM";
24 const char SpectrumSolverWrapper::SPECTRUM_SOLVER_MEM_BURG_AICc[] = "Burg's MEM AICc";
25 const char SpectrumSolverWrapper::SPECTRUM_SOLVER_MEM_BURG_MDL[] = "Burg's MEM MDL";
26 const char SpectrumSolverWrapper::SPECTRUM_SOLVER_AR_YW_AICc[] = "Yule-Walker AR AICc";
27 const char SpectrumSolverWrapper::SPECTRUM_SOLVER_AR_YW_MDL[] = "Yule-Walker AR MDL";
28 #ifdef USE_FREQ_ESTM
29  const char SpectrumSolverWrapper::SPECTRUM_SOLVER_MEM_STRICT_EV[] = "EV+Strict MEM";
30  const char SpectrumSolverWrapper::SPECTRUM_SOLVER_MUSIC_AIC[] = "MUSIC AIC";
31  const char SpectrumSolverWrapper::SPECTRUM_SOLVER_MUSIC_MDL[] = "MUSIC MDL";
32  const char SpectrumSolverWrapper::SPECTRUM_SOLVER_EV_AIC[] = "Eigenvector AIC";
33  const char SpectrumSolverWrapper::SPECTRUM_SOLVER_EV_MDL[] = "Eigenvector MDL";
34  const char SpectrumSolverWrapper::SPECTRUM_SOLVER_MVDL[] = "Capon's MVDL(MLM)";
35 #endif
36 const char SpectrumSolverWrapper::SPECTRUM_SOLVER_LS_HQ[] = "LeastSquare HQ";
37 const char SpectrumSolverWrapper::SPECTRUM_SOLVER_LS_AICc[] = "LeastSquare AICc";
38 const char SpectrumSolverWrapper::SPECTRUM_SOLVER_LS_MDL[] = "LeastSquare MDL";
39 
40 const char SpectrumSolverWrapper::WINDOW_FUNC_DEFAULT[] = "Rect";
41 const char SpectrumSolverWrapper::WINDOW_FUNC_HANNING[] = "Hanning";
42 const char SpectrumSolverWrapper::WINDOW_FUNC_HAMMING[] = "Hamming";
43 const char SpectrumSolverWrapper::WINDOW_FUNC_FLATTOP[] = "Flat-Top";
44 const char SpectrumSolverWrapper::WINDOW_FUNC_BLACKMAN[] = "Blackman";
45 const char SpectrumSolverWrapper::WINDOW_FUNC_BLACKMAN_HARRIS[] = "Blackman-Harris";
46 const char SpectrumSolverWrapper::WINDOW_FUNC_KAISER_1[] = "Kaiser a=3";
47 const char SpectrumSolverWrapper::WINDOW_FUNC_KAISER_2[] = "Kaiser a=7.2";
48 const char SpectrumSolverWrapper::WINDOW_FUNC_KAISER_3[] = "Kaiser a=15";
49 
50 SpectrumSolverWrapper::SpectrumSolverWrapper(const char *name, bool runtime,
51  const shared_ptr<XComboNode> selector, const shared_ptr<XComboNode> windowfunc,
52  const shared_ptr<XDoubleNode> windowlength, bool leastsquareonly)
53  : XNode(name, runtime), m_selector(selector), m_windowfunc(windowfunc), m_windowlength(windowlength) {
54  if(windowfunc) {
55  windowfunc->iterate_commit([=](Transaction &tr){
56  tr[ *windowfunc].add(WINDOW_FUNC_DEFAULT);
57  tr[ *windowfunc].add(WINDOW_FUNC_HANNING);
58  tr[ *windowfunc].add(WINDOW_FUNC_HAMMING);
59  tr[ *windowfunc].add(WINDOW_FUNC_BLACKMAN);
60  tr[ *windowfunc].add(WINDOW_FUNC_BLACKMAN_HARRIS);
61  tr[ *windowfunc].add(WINDOW_FUNC_FLATTOP);
62  tr[ *windowfunc].add(WINDOW_FUNC_KAISER_1);
63  tr[ *windowfunc].add(WINDOW_FUNC_KAISER_2);
64  tr[ *windowfunc].add(WINDOW_FUNC_KAISER_3);
65  });
66  }
67  if(selector) {
68  Snapshot shot = selector->iterate_commit([=](Transaction &tr){
69  if( !leastsquareonly) {
70  tr[ *selector].add(SPECTRUM_SOLVER_ZF_FFT);
71  tr[ *selector].add(SPECTRUM_SOLVER_MEM_STRICT);
72  // tr[ *selector].add(SPECTRUM_SOLVER_MEM_STRICT_EV);
73 #ifdef USE_FREQ_ESTM
74  tr[ *selector].add(SPECTRUM_SOLVER_MVDL);
75  tr[ *selector].add(SPECTRUM_SOLVER_EV_MDL);
76  tr[ *selector].add(SPECTRUM_SOLVER_MUSIC_MDL);
77 #endif
78  tr[ *selector].add(SPECTRUM_SOLVER_MEM_BURG_AICc);
79  tr[ *selector].add(SPECTRUM_SOLVER_MEM_BURG_MDL);
80  tr[ *selector].add(SPECTRUM_SOLVER_AR_YW_AICc);
81  tr[ *selector].add(SPECTRUM_SOLVER_AR_YW_MDL);
82  // tr[ *selector].add(SPECTRUM_SOLVER_MEM_STRICT_BURG);
83  }
84  tr[ *selector].add(SPECTRUM_SOLVER_LS_HQ);
85  tr[ *selector].add(SPECTRUM_SOLVER_LS_AICc);
86  tr[ *selector].add(SPECTRUM_SOLVER_LS_MDL);
87 
88  m_lsnOnChanged = tr[ *selector].onValueChanged().connectWeakly(
89  shared_from_this(), &SpectrumSolverWrapper::onSolverChanged);
90  });
91  onSolverChanged(shot, selector.get());
92  }
93 }
94 SpectrumSolverWrapper::~SpectrumSolverWrapper() {
95  if(m_windowfunc) {
96  trans( *m_windowfunc).clear();
97  }
98  if(m_selector) {
99  trans( *m_selector).clear();
100  }
101 }
102 FFT::twindowfunc
103 SpectrumSolverWrapper::windowFunc(const Snapshot &shot) const {
104  FFT::twindowfunc func = &FFT::windowFuncRect;
105  if(shot[ *m_windowfunc]) {
106  if(shot[ *m_windowfunc].to_str() == WINDOW_FUNC_HANNING) func = &FFT::windowFuncHanning;
107  if(shot[ *m_windowfunc].to_str() == WINDOW_FUNC_HAMMING) func = &FFT::windowFuncHamming;
108  if(shot[ *m_windowfunc].to_str() == WINDOW_FUNC_FLATTOP) func = &FFT::windowFuncFlatTop;
109  if(shot[ *m_windowfunc].to_str() == WINDOW_FUNC_BLACKMAN) func = &FFT::windowFuncBlackman;
110  if(shot[ *m_windowfunc].to_str() == WINDOW_FUNC_BLACKMAN_HARRIS) func = &FFT::windowFuncBlackmanHarris;
111  if(shot[ *m_windowfunc].to_str() == WINDOW_FUNC_KAISER_1) func = &FFT::windowFuncKaiser1;
112  if(shot[ *m_windowfunc].to_str() == WINDOW_FUNC_KAISER_2) func = &FFT::windowFuncKaiser2;
113  if(shot[ *m_windowfunc].to_str() == WINDOW_FUNC_KAISER_3) func = &FFT::windowFuncKaiser3;
114  }
115  return func;
116 }
117 void
118 SpectrumSolverWrapper::windowFuncs(std::deque<FFT::twindowfunc> &funcs) const {
119  funcs.clear();
120  funcs.push_back(&FFT::windowFuncRect);
121  funcs.push_back(&FFT::windowFuncHanning);
122  funcs.push_back(&FFT::windowFuncHamming);
123  funcs.push_back(&FFT::windowFuncFlatTop);
124  funcs.push_back(&FFT::windowFuncBlackman);
125  funcs.push_back(&FFT::windowFuncBlackmanHarris);
126  funcs.push_back(&FFT::windowFuncKaiser1);
127  funcs.push_back(&FFT::windowFuncKaiser2);
128  funcs.push_back(&FFT::windowFuncKaiser3);
129 }
130 
131 void
132 SpectrumSolverWrapper::onSolverChanged(const Snapshot &shot, XValueNodeBase *) {
133  shared_ptr<Payload::WrapperBase> wrapper;
134  bool has_window = true;
135  bool has_length = true;
136  if(m_selector) {
137  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_MEM_BURG_AICc) {
138  wrapper.reset(new Payload::Wrapper<MEMBurg>(new MEMBurg( &SpectrumSolver::icAICc)));
139  }
140  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_MEM_BURG_MDL) {
141  wrapper.reset(new Payload::Wrapper<MEMBurg>(new MEMBurg( &SpectrumSolver::icMDL)));
142  }
143  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_AR_YW_AICc) {
144  wrapper.reset(new Payload::Wrapper<YuleWalkerAR>(new YuleWalkerAR( &SpectrumSolver::icAICc)));
145  }
146  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_AR_YW_MDL) {
147  wrapper.reset(new Payload::Wrapper<YuleWalkerAR>(new YuleWalkerAR( &SpectrumSolver::icMDL)));
148  }
149 #ifdef USE_FREQ_ESTM
150  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_MUSIC_AIC) {
151  wrapper.reset(new Payload::Wrapper<MUSIC>(new MUSIC( &SpectrumSolver::icAIC)));
152  }
153  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_MUSIC_MDL) {
154  wrapper.reset(new Payload::Wrapper<MUSIC>(new MUSIC( &SpectrumSolver::icMDL)));
155  }
156  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_EV_AIC) {
157  wrapper.reset(new Payload::Wrapper<EigenVectorMethod>(new EigenVectorMethod( &SpectrumSolver::icAIC)));
158  }
159  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_EV_MDL) {
160  wrapper.reset(new Payload::Wrapper<EigenVectorMethod>(new EigenVectorMethod( &SpectrumSolver::icMDL)));
161  }
162  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_MVDL) {
163  wrapper.reset(new Payload::Wrapper<MVDL>(new MVDL));
164  }
165  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_MEM_STRICT_EV) {
166  wrapper.reset(new Payload::Wrapper<CompositeSpectrumSolver<MEMStrict, EigenVectorMethod> >(
168  }
169 #endif
170  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_MEM_STRICT) {
171  wrapper.reset(new Payload::Wrapper<MEMStrict>(new MEMStrict));
172  }
173  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_MEM_STRICT_BURG) {
174  wrapper.reset(new Payload::Wrapper<CompositeSpectrumSolver<MEMStrict, MEMBurg> >(
176  }
177  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_LS_HQ) {
178  wrapper.reset(new Payload::Wrapper<FreqEstLeastSquare>(new FreqEstLeastSquare( &SpectrumSolver::icHQ)));
179  }
180  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_LS_AICc) {
181  wrapper.reset(new Payload::Wrapper<FreqEstLeastSquare>(new FreqEstLeastSquare( &SpectrumSolver::icAICc)));
182  }
183  if(shot[ *m_selector].to_str() == SPECTRUM_SOLVER_LS_MDL) {
184  wrapper.reset(new Payload::Wrapper<FreqEstLeastSquare>(new FreqEstLeastSquare( &SpectrumSolver::icMDL)));
185  }
186  }
187  if( !wrapper) {
188  wrapper.reset(new Payload::Wrapper<FFTSolver>(new FFTSolver));
189  }
190  if(m_windowfunc)
191  m_windowfunc->setUIEnabled(has_window);
192  if(m_windowlength)
193  m_windowlength->setUIEnabled(has_length);
194  iterate_commit([=](Transaction &tr){
195  tr[ *this].m_wrapper = wrapper;
196  });
197 }

Generated for KAME4 by  doxygen 1.8.3