Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /Conograph/trunk/src/lattice_symmetry/LatticeFigureOfMeritToDisplay.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 33 - (hide annotations) (download) (as text)
Wed Sep 7 04:38:51 2016 UTC (7 years, 6 months ago) by rtomiyasu
File MIME type: text/x-c++src
File size: 10468 byte(s)
The output format for base-centered monoclinic cells was corrected.
1 rtomiyasu 3 /*
2     * The MIT License
3    
4     Conograph (powder auto-indexing program)
5    
6     Copyright (c) <2012> <Ryoko Oishi-Tomiyasu, KEK>
7    
8     Permission is hereby granted, free of charge, to any person obtaining a copy
9     of this software and associated documentation files (the "Software"), to deal
10     in the Software without restriction, including without limitation the rights
11     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12     copies of the Software, and to permit persons to whom the Software is
13     furnished to do so, subject to the following conditions:
14    
15     The above copyright notice and this permission notice shall be included in
16     all copies or substantial portions of the Software.
17    
18     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24     THE SOFTWARE.
25     *
26     */
27 rtomiyasu 25 #include "gather_q_of_3D_lattice.hh"
28 rtomiyasu 3 #include "../utility_func/zmath.hh"
29     #include "../zlog/zlog.hh"
30     #include "../ControlParam.hh"
31     #include "../PeakPosData.hh"
32     #include "LatticeFigureOfMeritToDisplay.hh"
33    
34 rtomiyasu 33 LatticeFigureOfMeritToDisplay::LatticeFigureOfMeritToDisplay()
35     : m_type_of_reflection_conditions(-1), m_showsTicks(false)
36 rtomiyasu 3 {
37     }
38    
39    
40 rtomiyasu 33 void LatticeFigureOfMeritToDisplay::setTypeOfSystematicAbsences(const Int4& arg)
41     {
42     assert(arg < putNumberOfTypesOfSystematicAbsences(this->putLatticeFigureOfMerit().putBravaisType()));
43     m_type_of_reflection_conditions = arg;
44     };
45    
46    
47 rtomiyasu 3 void LatticeFigureOfMeritToDisplay::putStandardMillerIndicesToFit(vector< VecDat3<Int4> >& hkl_to_fit,
48     vector<bool>& fix_or_fit_flag) const
49     {
50     const Int4 num_Q = m_associated_hkl_tray.size();
51     const Double cv2 = m_latfom.putCriticalValueSquare();
52    
53     fix_or_fit_flag.resize(num_Q);
54     hkl_to_fit.resize(num_Q);
55    
56     vector< multimap<Double, vector<HKL_Q>::const_iterator> >::const_iterator it = m_associated_hkl_tray.begin();
57     Double diff;
58     for(Int4 i=0; i<num_Q; i++, it++)
59     {
60     if( it->empty() )
61     {
62     hkl_to_fit[i] = 0;
63     fix_or_fit_flag[i] = false;
64     continue;
65     }
66    
67     diff = m_qdata[i].q - it->begin()->second->Q();
68     hkl_to_fit[i] = it->begin()->second->HKL();
69    
70     if( diff * diff <= cv2 * m_qdata[i].q_var ) fix_or_fit_flag[i] = true;
71     else fix_or_fit_flag[i] = false;
72     }
73     }
74    
75    
76     void LatticeFigureOfMeritToDisplay::resetMillerIndicesInRange(const Int4& num_fit_data)
77     {
78     assert( num_fit_data <= (Int4)m_qdata.size() );
79    
80     const Double cv2 = m_latfom.putCriticalValueSquare();
81    
82     range<Double> qobs_range;
83     qobs_range.begin = 0.0;
84     qobs_range.end = m_qdata.rbegin()->q + sqrt(cv2 * m_qdata.rbegin()->q_var);
85    
86 rtomiyasu 33 m_latfom.putMillerIndicesInRange(qobs_range.end, m_type_of_reflection_conditions, m_cal_hkl_tray);
87 rtomiyasu 3 m_associated_hkl_tray.clear();
88     m_associated_hkl_tray.resize(num_fit_data);
89    
90     vector< multimap<Double, vector<HKL_Q>::const_iterator> >::iterator it = m_associated_hkl_tray.begin();
91     vector<HKL_Q>::const_iterator it2_begin, it2_end;
92     for(Int4 i=0; i<num_fit_data; i++, it++)
93     {
94     const Double diff = sqrt(cv2 * m_qdata[i].q_var);
95     it2_begin = lower_bound( m_cal_hkl_tray.begin(), m_cal_hkl_tray.end(), HKL_Q(0, m_qdata[i].q - diff) );
96     it2_end = upper_bound( it2_begin, (vector<HKL_Q>::const_iterator)m_cal_hkl_tray.end(), HKL_Q(0, m_qdata[i].q + diff) );
97     if( it2_begin < it2_end )
98     {
99     for(vector<HKL_Q>::const_iterator it2=it2_begin; it2<it2_end; it2++)
100     {
101     it->insert( multimap<Double, vector<HKL_Q>::const_iterator>::value_type(fabs(m_qdata[i].q-it2->Q()), it2) );
102     }
103     }
104     else
105     {
106     if( m_cal_hkl_tray.begin() < it2_begin )
107     {
108     it->insert( multimap<Double, vector<HKL_Q>::const_iterator>::value_type(fabs(m_qdata[i].q - (it2_begin-1)->Q()), it2_begin-1) );
109     }
110     if( it2_begin < m_cal_hkl_tray.end() )
111     {
112     it->insert( multimap<Double, vector<HKL_Q>::const_iterator>::value_type(fabs(m_qdata[i].q - it2_begin->Q()), it2_begin) );
113     }
114     }
115     }
116     }
117    
118    
119    
120     Int4 LatticeFigureOfMeritToDisplay::fitLatticeParameter(const PeakPosData& pdata,
121     const vector<etype_ID>& fitflag, const Int4& Max_ITNUM, const Double& limiter)
122     {
123     vector< VecDat3<Int4> > hkl_to_fit = m_hkl_to_fit;
124     vector<bool> fix_or_fit_flag = m_fix_or_fit_flag; // 0:fix, 1:fit.
125     Int4 itnum = 0;
126     try{
127     do{
128     const Double old_fom = m_latfom.putFiguresOfMerit().putFigureOfMeritWolff();
129     ZLOG_INFO( "\n" + num2str( ++itnum ) + ") Initial " + m_latfom.putFiguresOfMerit().putLabel_FigureOfMeritWolff() + " = " + num2str(old_fom) + "\n" );
130    
131     vector<QData> qdata_modified;
132     pair<bool, ZErrorMessage> ans = m_latfom.fitLatticeParameter(m_qdata,
133     hkl_to_fit, fix_or_fit_flag, true,
134     pdata, fitflag, Max_ITNUM,
135     VCData::putPeakQData().size(), qdata_modified);
136    
137     if( ans.second.putErrorType() != ZErrorNoError )
138     {
139     throw ans.second;
140     }
141     else if( !ans.first )
142     {
143     ZLOG_INFO( num2str( m_latfom.putFiguresOfMerit().putLabel_FigureOfMeritWolff() ) + " was not improved.\n\n" );
144     break;
145     }
146     else
147     {
148     // Optimization has succeeded.
149     const Double& new_fom = m_latfom.putFiguresOfMerit().putFigureOfMeritWolff();
150     ZLOG_INFO( num2str( m_latfom.putFiguresOfMerit().putLabel_FigureOfMeritWolff() ) + " of optimized solution = " + num2str(new_fom) + "\n" );
151     m_qdata = qdata_modified;
152     resetMillerIndicesInRange(m_associated_hkl_tray.size());
153     putStandardMillerIndicesToFit(hkl_to_fit, fix_or_fit_flag);
154     if( (new_fom - old_fom) < old_fom * limiter ) break;
155     }
156     } while(true);
157     }
158     catch(const ZErrorMessage& zerr)
159     {
160     ZLOG_ERROR( zerr.printErrorLog() );
161     }
162    
163     if( itnum > 2 )
164     {
165     m_hkl_to_fit = hkl_to_fit;
166     m_fix_or_fit_flag = fix_or_fit_flag;
167     }
168    
169     return itnum-1;
170     }
171    
172    
173     void LatticeFigureOfMeritToDisplay::putCalculatedPeakPosInRange(const ControlParam& cdata,
174     Vec_DP& cal_pos_tray) const
175     {
176     static const Double MAX_DP = numeric_limits<Double>::max();
177     const vector<ZParawError>& peak_shift_param_rad = m_latfom.putPeakShiftParamRadian();
178    
179     cal_pos_tray.clear();
180     if( cdata.IsAngleDispersion() )
181     {
182     for(vector<HKL_Q>::const_iterator it=m_cal_hkl_tray.begin(); it<m_cal_hkl_tray.end(); it++)
183     {
184     if( cdata.putWaveLength() * cdata.putWaveLength() * it->Q() > 4.0 ) break;
185     cal_pos_tray.push_back( cal_theta2_deg(peak_shift_param_rad, cdata.putWaveLength(), sqrt(it->Q()) ) );
186     }
187    
188     const Int4 isize = m_cal_hkl_tray.size();
189     cal_pos_tray.resize(isize, -MAX_DP);
190     }
191     else
192     {
193     for(vector<HKL_Q>::const_iterator it=m_cal_hkl_tray.begin(); it<m_cal_hkl_tray.end(); it++)
194     {
195     cal_pos_tray.push_back( put_polynomial_value(cdata.putConvParam(), 1.0 / sqrt(it->Q()) ) );
196     }
197     }
198     }
199    
200    
201     void LatticeFigureOfMeritToDisplay::putPeakPosToFit(const ControlParam& cdata,
202     Vec_DP& cal_q_tray, Vec_DP& cal_pos_tray) const
203     {
204     const Vec_DP& conv_param = cdata.putConvParam();
205     const vector<ZParawError>& peak_shift_param_rad = m_latfom.putPeakShiftParamRadian();
206     const Double& wave_length = cdata.putWaveLength();
207    
208     const vector< VecDat3<Int4> >& hkl_to_fit = putMillerIndicesToFit();
209 rtomiyasu 25 const size_t num_obsQ = hkl_to_fit.size();
210 rtomiyasu 3 const SymMat<Double>& dbl_S = m_latfom.putOptimizedForm().first;
211    
212     cal_q_tray.clear();
213     cal_pos_tray.clear();
214     cal_q_tray.resize(num_obsQ);
215     cal_pos_tray.resize(num_obsQ);
216 rtomiyasu 25 for(size_t l=0; l<num_obsQ; l++)
217 rtomiyasu 3 {
218     const VecDat3<Int4>& hkl = hkl_to_fit.at(l);
219     const Double q_cal = norm(hkl, dbl_S);
220     cal_q_tray.at(l) = q_cal;
221    
222     if( cdata.IsAngleDispersion() )
223     {
224     cal_pos_tray.at(l) = cal_theta2_deg(peak_shift_param_rad, wave_length, sqrt(q_cal));
225     }
226     else
227     {
228     cal_pos_tray.at(l) = put_polynomial_value(conv_param, 1.0 / sqrt(q_cal));
229     }
230     }
231     }
232    
233    
234    
235    
236     void LatticeFigureOfMeritToDisplay::printIndexingResult(const ControlParam& cdata,
237     const PeakPosData& pdata,
238     const Int4& label_start0,
239     ostream* os) const
240     {
241     static const Double DegRad = 180.0 / PI();
242    
243     Int4 label_start = label_start0;
244     os->width(label_start);
245     *os << "" << "<IndexingResults>\n";
246     label_start++;
247    
248     const Vec_DP& posdata = pdata.putPeakPosXData();
249     const Vec_DP& posdata_err = pdata.putPeakWidthData();
250    
251     const vector<Int4>& pos_qindex = VCData::putPeakQIndex();
252    
253     const vector< VecDat3<Int4> >& hkl_to_fit = putMillerIndicesToFit();
254     const vector<bool>& fix_or_fit_flag = putFittingIDs();
255 rtomiyasu 25 const size_t num_obsQ = hkl_to_fit.size();
256 rtomiyasu 3
257     Vec_DP cal_q_tray, cal_pos_tray;
258     this->putPeakPosToFit(cdata, cal_q_tray, cal_pos_tray);
259    
260     os->width(label_start);
261     *os << "" << "<!-- q_obs, q_err, q_cal, peak_pos, peak_width, pos_cal, hkl, fix_or_fit.-->\n";
262 rtomiyasu 25 for(size_t l=0; l<num_obsQ; l++)
263 rtomiyasu 3 {
264     os->width(15);
265     *os << m_qdata.at(l).q;
266    
267     os->width(15);
268     *os << sqrt(m_qdata.at(l).q_var);
269    
270     os->width(15);
271     *os << cal_q_tray.at(l);
272    
273     os->width(15);
274     *os << posdata[pos_qindex.at(l)];
275    
276     os->width(15);
277     *os << posdata_err[pos_qindex.at(l)];
278    
279     os->width(15);
280     *os << cal_pos_tray.at(l);
281    
282     const VecDat3<Int4>& hkl = hkl_to_fit.at(l);
283    
284     os->width(15);
285     *os << "[" + num2str<Int4>( hkl[0] ) + ","
286     + num2str<Int4>( hkl[1] ) + ","
287     + num2str<Int4>( hkl[2] ) + "]";
288    
289     os->width(5);
290     if( fix_or_fit_flag.at(l) ) *os << "1";
291     else *os << "0";
292    
293     *os << endl;
294     }
295    
296     label_start--;
297     os->width(label_start);
298     *os << "" << "</IndexingResults>\n\n";
299    
300     if( !cdata.IsAngleDispersion() ) return;
301    
302     label_start = label_start0;
303     os->width(label_start);
304     *os << "" << "<OptimizedZeroShitParameters>\n";
305     label_start++;
306    
307     vector<ZParawError> peak_shift_param_rad = m_latfom.putPeakShiftParamRadian();
308     const Int4 param_num = peak_shift_param_rad.size();
309     for(Int4 i=0; i<param_num; i++)
310     {
311     os->width(label_start);
312     *os << "" << "<Parameter>";
313     os->width(15);
314     *os << peak_shift_param_rad[i].value * DegRad;
315     *os << " </Parameter>";
316    
317     *os << " <Error>";
318     os->width(15);
319     *os << peak_shift_param_rad[i].error * DegRad;
320     *os << " </Error>\n";
321     }
322    
323     label_start--;
324     os->width(label_start);
325     *os << "" << "</OptimizedZeroShitParameters>\n";
326     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26