Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 33 - (show 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 /*
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 #include "gather_q_of_3D_lattice.hh"
28 #include "../utility_func/zmath.hh"
29 #include "../zlog/zlog.hh"
30 #include "../ControlParam.hh"
31 #include "../PeakPosData.hh"
32 #include "LatticeFigureOfMeritToDisplay.hh"
33
34 LatticeFigureOfMeritToDisplay::LatticeFigureOfMeritToDisplay()
35 : m_type_of_reflection_conditions(-1), m_showsTicks(false)
36 {
37 }
38
39
40 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 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 m_latfom.putMillerIndicesInRange(qobs_range.end, m_type_of_reflection_conditions, m_cal_hkl_tray);
87 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 const size_t num_obsQ = hkl_to_fit.size();
210 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 for(size_t l=0; l<num_obsQ; l++)
217 {
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 const size_t num_obsQ = hkl_to_fit.size();
256
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 for(size_t l=0; l<num_obsQ; l++)
263 {
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