Develop and Download Open Source Software

Browse Subversion Repository

Contents of /Conograph/trunk/src/main_indexing.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (show annotations) (download) (as text)
Mon Jul 7 02:35:51 2014 UTC (9 years, 8 months ago) by rtomiyasu
File MIME type: text/x-c++src
File size: 17954 byte(s)
Source codes of version 0.9.99
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 #ifdef _OPENMP
28 #include <omp.h>
29 #endif
30 #include <iostream>
31 #include <string>
32 #include <stdexcept>
33 #include <cstdlib>
34 #include <time.h>
35 #include "ControlFile.hh"
36 #include "ControlParam.hh"
37 #include "IndexingLattice.hh"
38 #include "SortingLattice.hh"
39 #include "lattice_symmetry/OutputInfo.hh"
40 #include "lattice_symmetry/VCLatticeFigureOfMeritToCheckSymmetry.hh"
41 #include "lattice_symmetry/LatticeFigureOfMeritToDisplay.hh"
42 #include "LatticeWithSameQ/LatticeMetricTensor.hh"
43 #include "LatticeWithSameQ/LatticeWithSameQ.hh"
44 #include "LatticeWithSameQ/p_out_same_q.hh"
45 #include "zerror_type/error_out.hh"
46 #include "zerror_type/error_mes.hh"
47 #include "zlog/zlog.hh"
48 #include "p_out_indexing.hh"
49 #include "chToqValue.hh"
50 #include "utility_func/stopx.hh"
51 #include "utility_func/zstring.hh"
52
53
54 using namespace std;
55
56
57 int main(int argc, char* argv[])
58 {
59 clock_t start = clock(); /* Record the starting time. */
60
61 // For interruption signal.
62 SetSignal(SIGINT);
63
64 static const string controlFile = "cntl.inp.xml";
65 static const string InputFileLabel = "ZCodeParameters";
66
67 try{
68 CRLog::append(new CCoutListner());
69 CRLog::append(new FileoutListner("LOG_CONOGRAPH.txt", zListnerID(1)));
70
71 ZLOG_INFO( "Reading " + controlFile + "...\n\n" );
72
73 ControlFile cf;
74 ZErrorMessage zerr;
75 zerr = cf.readFile(controlFile, InputFileLabel);
76 if( zerr.putErrorType() != ZErrorNoError) throw zerr;
77
78 PeakPosData pData;
79 zerr = pData.readFile(cf.putPeakDataFileName());
80 if( zerr.putErrorType() != ZErrorNoError) throw zerr;
81
82 if( pData.putPeakPosXData().size() < 3 )
83 {
84 throw nerror_arg("NUMBER OF INPUT REFLECTIONS IS TOO SMALL.", __FILE__, __LINE__, __FUNCTION__);
85 }
86
87 ControlParam cData;
88 zerr = cData.readFile(cf.putControlParamFileName(), InputFileLabel);
89 if( zerr.putErrorType() != ZErrorNoError ) throw zerr;
90
91 #ifdef _OPENMP
92 omp_set_num_threads(min(omp_get_max_threads(), cData.putNumberOfThreadsToUse()));
93 ZLOG_INFO( "The number of threads is set to " + num2str( min(omp_get_max_threads(), cData.putNumberOfThreadsToUse()) ) + "\n" );
94 #endif
95
96 // change the peak-positions into q-values.
97 vector<QData> qData;
98 vector<Int4> qIndexData;
99 zerr = chToqValue(cData, pData, qData, qIndexData);
100 if( zerr.putErrorType() != ZErrorNoError) throw zerr;
101
102 // Set Qdata as a static member of VCData.
103 VCData::setQData(qData, qIndexData);
104
105 #ifdef DEBUG
106 ZLOG_INFO( "Outputting q-values...\nNo., qvalue, error_of_qvalue, peakpos, peak-width, flag\n" );
107 stringstream strstream;
108 for(UInt4 k=0; k<qData.size(); k++)
109 {
110 strstream << qIndexData[k] + 1 << " "
111 << qData[k].q << " "
112 << sqrt( qData[k].q_var ) << " "
113 << (pData.putPeakPosXData())[ qIndexData[k] ] << " "
114 << (pData.putPeakWidthData())[ qIndexData[k] ] << " "
115 << (pData.putToUseFlag())[ qIndexData[k] ] << endl;
116 }
117 ZLOG_INFO( strstream.str() + "\n" );
118 #endif
119
120 if( (Int4)qData.size() < 3 )
121 {
122 throw ZErrorMessage("The number of q-values is too small : " + num2str<Int4>(qData.size()), __FILE__, __LINE__, __FUNCTION__);
123 }
124
125 // Check if the range of q-values is large enough.
126 zerr = cData.setAutomaticallyComputedParam(qData);
127 if( zerr.putErrorType() != ZErrorNoError ) throw zerr;
128 const Double inv_d_max = sqrt( min( qData.begin() + cData.putMaxPeakNum(), qData.end()-1 )->q );
129 const Double inv_d_min = sqrt( qData.begin()->q );
130 ZLOG_INFO( "\nThe range of d^*-value : sqrt(the minimum of q-values)--sqrt(the maximum of q-values) = "
131 + num2str( inv_d_min ) + "--" + num2str( inv_d_max ) + "\n" );
132
133 // Estimation of zero point shift.
134 if( cData.IsAngleDispersion()
135 && cData.putPeakShiftFunctionType() != kPeakShiftFunction_Type0 )
136 {
137 vector< pair<Int4, Int4> > pair_of_q;
138 vector< Double > zero_point_shift_deg;
139 fitZeroPointShift(pData, 10, pair_of_q, zero_point_shift_deg);
140
141 ZLOG_INFO( "-------- Estimated zero point shift from pairs of peaks --------\nNo. of peaks (ratio of sin(theta)) : zero point shift\n" );
142 const Int4 ISIZE = zero_point_shift_deg.size();
143 if( ISIZE > 0 )
144 {
145 const Vec_DP& posdata = pData.putPeakPosXData();
146 static const Double RadDeg = PI() / 180.0; // = pi / 180.0.
147 stringstream strstream;
148 strstream.precision(4);
149 strstream.setf(ios::fixed, ios::floatfield);
150 for(Int4 i=0; i<ISIZE; i++)
151 {
152 strstream.width(4);
153 strstream << num2str( pair_of_q[i].first + 1 ) + "&";
154 strstream.width(4);
155 strstream << num2str( pair_of_q[i].second + 1 ) + " ("
156 << sin(0.5*posdata[ pair_of_q[i].second ]*RadDeg) / sin(0.5*posdata[ pair_of_q[i].first ]*RadDeg) << "): ";
157 strstream.width(7);
158 strstream << zero_point_shift_deg[i] << "\n";
159 }
160 ZLOG_INFO( strstream.str() );
161 }
162 else
163 {
164 ZLOG_INFO( "Could not estimate because the number of peaks is small\n" );
165 }
166 ZLOG_INFO( "-------- Estimated zero point shift from pairs of peaks --------\n" );
167 }
168
169 // Indexing.
170 IndexingLattice clc;
171 clc.setParam(cData);
172
173 clc.determineTwoDimLattices(pData, "DEBUG_CONOGRAPH");
174 clc.determineThreeDimLattices("DEBUG_CONOGRAPH");
175 const vector<SymMat43_VCData>& S_super = clc.putThreeDimTopographNodes();
176
177 ZLOG_INFO( "The program has obtained " + num2str( S_super.size() )
178 + " unit-cell parameters in CPU time : " + num2str( (clock() - start) / CLOCKS_PER_SEC )
179 + " [sec.]\n\n" );
180
181 // Indexing.
182 static const Int4 NUM_LS = put_number_of_bravais_types();
183 vector<VCLatticeFigureOfMeritToCheckSymmetry> lattice_result[NUM_LS];
184
185 SortingLattice srl;
186 srl.setParam(cData);
187
188 start = clock(); /* Record the starting time. */
189 srl.putLatticeCandidatesForEachBravaisTypes(S_super, cData.putThresholdOnNormM(), cData.putThresholdOnRevM(),
190 cData.putMaxSizeForEachBRAVAIS(),
191 cData.putBaseCenteredAxis(), cData.putRhombohedralAxis(), lattice_result);
192
193 ZLOG_INFO( "Selecting lattices with the best figure of merit among almost equivalent solutions...\n" );
194 // After this method, each lattice_result[i] are sorted by unit-cell volumes.
195 srl.setNumberOfNeighbors(cData.putBaseCenteredAxis(), OutputInfo::CmpFunc[(Int4)SCM], lattice_result);
196
197 ZLOG_INFO( "The Bravais lattice determination and refinement of unit-cell parameters finish in CPU time : " + num2str( (clock() - start) / CLOCKS_PER_SEC ) + " [sec.]\n\n" );
198
199 // Sort by sort_criterion.
200 static const eSortCriterion sort_criterion = SCM;
201 for(Int4 i=0; i<NUM_LS; i++)
202 {
203 stable_sort( lattice_result[i].begin(), lattice_result[i].end(), OutputInfo::CmpFunc[(Int4)sort_criterion] );
204 }
205
206 // Sets output_flag.
207 ZLOG_INFO( "Outputting results...\n" );
208 OutputInfo outinfo[NUM_LS];
209 for(Int4 i=0; i<NUM_LS; i++)
210 {
211 outinfo[i].setLabel(lattice_result[i], cData);
212 }
213
214 // Solution having the top M is output as the best solution.
215 printHKLdata(lattice_result, outinfo, sort_criterion, cData, pData,
216 cf.putOutputFileName());
217
218 ZLOG_INFO( "Input a lattice number in " + cf.putOutputFileName()
219 + "\n(Then, the program outputs an IGOR text file for comparison of calculated peak-positions with the powder diffraction pattern.\n"
220 + "Input \"quit\" to finish the program.) :" );
221
222 string str;
223 Int4 cs_index;
224 Int4 cs_label;
225 vector<LatticeFigureOfMeritToDisplay> selected_lattice_tray;
226
227 do{
228 cin >> str;
229 if( str == "quit" )
230 {
231 ZLOG_INFO( "quit.\n" );
232 break;
233 }
234
235 if( cin.fail() || str.length() < 3
236 || !str2num(str.substr(0,2), cs_index) || !str2num(str.substr(2), cs_label)
237 || cs_index <= 0 || put_number_of_bravais_types() < cs_index
238 || cs_label <= 0 )
239 {
240 ZLOG_ERROR( "Wrong lattice number.\n" );
241 }
242 else
243 {
244 const Int4 index = outinfo[cs_index-1].putIndex(cs_label);
245
246 if( index < 0 )
247 {
248 ZLOG_ERROR( "Wrong lattice number.\n" );
249 }
250 else
251 {
252 const LatticeFigureOfMeritZeroShift& selected_lattice0 = lattice_result[cs_index-1][index].putLatticeFigureOfMerit();
253 const size_t n = selected_lattice_tray.size();
254 selected_lattice_tray.resize(n+1);
255
256 VecDat3<Double> length_axis, angle_axis;
257 selected_lattice0.putReducedLatticeConstantsDegree(cData.putBaseCenteredAxis(), cData.putRhombohedralAxis(), length_axis, angle_axis);
258
259 ZLOG_INFO( "Optimizing lattice parameters by linear least squares...\n" );
260 bool fitting_succeed = false;
261 try{
262 // Starts from setting the Bravais-type and unit-cell parameters.
263 zerr = selected_lattice_tray[n].setLatticeConstantsDegree(selected_lattice0.enumBravaisType(), cData.putBaseCenteredAxis(), cData.putRhombohedralAxis(), length_axis, angle_axis);
264 if( zerr.putErrorType() != ZErrorNoError ) throw zerr;
265
266 selected_lattice_tray[n].putOptimizedLatticeConstantsDegree(cData.putBaseCenteredAxis(), cData.putRhombohedralAxis(), length_axis, angle_axis);
267 ZLOG_INFO( "Initial unit-cell parameters : "
268 + num2str( length_axis[0] ) + " " + num2str( length_axis[1] ) + " " + num2str( length_axis[2] ) + " "
269 + num2str( angle_axis[0] ) + " " + num2str( angle_axis[1] ) + " " + num2str( angle_axis[2] ) + "\n" );
270
271 zerr = selected_lattice_tray[n].setPeakShiftParamDegree(
272 selected_lattice0.putPeakShiftFunctionType(),
273 selected_lattice0.putWaveLength(),
274 selected_lattice0.putPeakShiftParamDegree(),
275 pData);
276 if( zerr.putErrorType() != ZErrorNoError ) throw zerr;
277 if( selected_lattice0.putPeakShiftFunctionType() != kPeakShiftFunction_Type0 )
278 {
279 ZLOG_INFO( "Wave-length: " + num2str( selected_lattice_tray[n].putLatticeFigureOfMerit().putWaveLength() ) + "\n"
280 + "Initial zero point shift: " + num2str(selected_lattice_tray[n].putPeakShiftParamDegree()[0].value ) + "\n" );
281 }
282
283 // Reduce the lattice parameters to be optimized.
284 selected_lattice_tray[n].reduceLatticeConstants();
285
286 selected_lattice_tray[n].putOptimizedLatticeConstantsDegree(cData.putBaseCenteredAxis(), cData.putRhombohedralAxis(), length_axis, angle_axis);
287 ZLOG_INFO( "Reduced unit-cell parameters : "
288 + num2str( length_axis[0] ) + " " + num2str( length_axis[1] ) + " " + num2str( length_axis[2] ) + " "
289 + num2str( angle_axis[0] ) + " " + num2str( angle_axis[1] ) + " " + num2str( angle_axis[2] ) + "\n" );
290
291
292 // Set figure of merits.
293 selected_lattice_tray[n].setFigureOfMerit(cData.putNumberOfReflectionsForFigureOfMerit());
294
295 // Index peaks and set flags.
296 selected_lattice_tray[n].resetMillerIndicesInRange(cData.putNumberOfReflectionsForFigureOfMerit());
297 selected_lattice_tray[n].resetMillerIndicesToFit();
298
299 // Set Miller indices for optimization.
300 zerr = selected_lattice_tray[n].setMillerIndicesToFit(selected_lattice_tray[n].putMillerIndicesToFit());
301 if( zerr.putErrorType() != ZErrorNoError ) throw zerr;
302 // Set Use/No Use IDs.
303 ZErrorMessage zerr = selected_lattice_tray[n].setFittingIDs(selected_lattice_tray[n].putFittingIDs());
304 if( zerr.putErrorType() != ZErrorNoError ) throw zerr;
305
306 if( selected_lattice0.putPeakShiftFunctionType() == kPeakShiftFunction_Type0 )
307 {
308 vector<etype_ID> peak_shift_fitflag(0, _ZRietveldIDVary);
309 fitting_succeed = selected_lattice_tray[n].fitLatticeParameter(pData, peak_shift_fitflag, 30, 1.0e-3); // All arguments are not used in this case.
310 }
311 else
312 {
313 vector<etype_ID> peak_shift_fitflag(1, _ZRietveldIDVary);
314 fitting_succeed = selected_lattice_tray[n].fitLatticeParameter(pData, peak_shift_fitflag, 30, 1.0e-3);
315 }
316 }
317 catch(const ZErrorMessage& zerr)
318 {
319 ZLOG_ERROR( zerr.printErrorLog() );
320 }
321
322 if( fitting_succeed )
323 {
324 selected_lattice_tray[n].putOptimizedLatticeConstantsDegree(cData.putBaseCenteredAxis(), cData.putRhombohedralAxis(), length_axis, angle_axis);
325 ZLOG_INFO( "Optimized unit-cell parameters : "
326 + num2str( length_axis[0] ) + " " + num2str( length_axis[1] ) + " " + num2str( length_axis[2] ) + " "
327 + num2str( angle_axis[0] ) + " " + num2str( angle_axis[1] ) + " " + num2str( angle_axis[2] ) + "\n)" );
328
329 if( selected_lattice0.putPeakShiftFunctionType() != kPeakShiftFunction_Type0 )
330 {
331 ZLOG_INFO( "Optimized zero point shift : " + num2str( selected_lattice_tray[n].putPeakShiftParamDegree()[0].value ) + "\n");
332 }
333 // Save the optimized solution in the original entry in lattice_result.
334 lattice_result[cs_index-1][index].setLatticeFigureOfMerit( selected_lattice_tray[n].putLatticeFigureOfMerit() );
335
336 // Reduce the lattice parameters.
337 selected_lattice_tray[n].reduceLatticeConstants();
338 selected_lattice_tray[n].putOptimizedLatticeConstantsDegree(cData.putBaseCenteredAxis(), cData.putRhombohedralAxis(), length_axis, angle_axis);
339 ZLOG_INFO( "Reduced unit-cell parameters : "
340 + num2str( length_axis[0] ) + " " + num2str( length_axis[1] ) + " " + num2str( length_axis[2] ) + " "
341 + num2str( angle_axis[0] ) + " " + num2str( angle_axis[1] ) + " " + num2str( angle_axis[2] ) + "\n\n" );
342 }
343
344 const Int4 num = selected_lattice_tray[n].putLatticeFigureOfMerit().checkDominantZone();
345 if( num > cData.putNumberOfReflectionsForFigureOfMerit() )
346 {
347 ZLOG_WARN( "A dominant zone exists. This is resolved by increasing the parameter <" + cData.putNumberOfReflectionsForFigureOfMeritLabel() + "> to a number more than " + num2str(num-1) + ".\n" );
348 }
349
350 ZLOG_INFO( "Checking coincidence of computed lines ...\n" );
351 LatticeWithSameQ lws;
352 lws.setParam( cData, selected_lattice_tray[n].putLatticeFigureOfMerit().putSellingReducedForm() );
353 pair<bool, Double> evaluation_ans;
354 lws.execute( evaluation_ans, selected_lattice_tray[n].putLatticeFigureOfMerit().putSellingReducedForm() );
355
356 if( !evaluation_ans.first )
357 {
358 ZLOG_WARN( "it is necessary to increase \"" + cData.putMaxQTocheckComputedLinesLabel()
359 + "\" or reduce " + cData.putResolutionTocheckComputedLinesLabel()
360 + "\" in order to obtain all the unit-cells with the same computed lines.\n" );
361 }
362
363 vector<LatticeFigureOfMerit> lattices_same_q;
364 lws.putLatticesWithSameQ(cData, selected_lattice_tray[n].putQDataModifiedWithNewPeakShiftParam(), lattices_same_q);
365
366 if( lattices_same_q.empty() )
367 {
368 ZLOG_INFO( "The unit-cell does not have the same computed lines as any other unit-cells.\n\n" );
369 }
370 else
371 {
372 ostringstream oss;
373 printSolutions(lattices_same_q, cData, &oss);
374 ZLOG_WARN( "The unit-cell have very similar computed lines as the following (the solution might not determined uniquely from peak positions):\n" + oss.str() );
375 }
376
377 string fname00, fname0;
378 removeFileExtension(cf.putOutputFileName(), fname00);
379 removeFileExtension(fname00, fname0);
380
381 const string output_igor_file_name = fname0 + "_lattice("
382 + put_bravais_type_name(selected_lattice_tray[n].putLatticeFigureOfMerit().enumBravaisType(), cData.putBaseCenteredAxis()) + ";"
383 + selected_lattice_tray[n].putLatticeFigureOfMerit().printOptimizedLatticeConstants(cData.putBaseCenteredAxis(), cData.putRhombohedralAxis(), 3) + ";"
384 + num2str<Double>(selected_lattice_tray[n].putLatticeFigureOfMerit().putFiguresOfMerit().putFigureOfMeritWolff(), 3) + ").histogramIgor";
385
386 printPeakPosition(cData, pData, selected_lattice_tray[n], lattices_same_q, output_igor_file_name);
387
388 ZLOG_INFO( "The program has output an IGOR text file : " + output_igor_file_name + "\n\n" );
389 }
390 }
391 ZLOG_INFO( "Input a lattice number in " + cf.putOutputFileName() + " :" );
392
393 } while( true );
394
395 // Selected lattice is output.
396 if( !selected_lattice_tray.empty() )
397 {
398 string fname00, fname0;
399 removeFileExtension(cf.putOutputFileName(), fname00);
400 removeFileExtension(fname00, fname0);
401
402 printHKLdata(selected_lattice_tray, cData, pData, fname0 +".index2.xml");
403
404 printPeakPosition(cData, pData, selected_lattice_tray, fname0 +"_lattices.histogramIgor");
405 }
406 }
407 catch(bad_alloc& ball){
408 ZErrorMessage zerr = nerror(ball, __FILE__, __LINE__, __FUNCTION__);
409 ZLOG_ERROR( zerr.printErrorLog() );
410 return 0;
411 }
412 catch(out_of_range&)
413 {
414 ZErrorMessage zerr("out_of_range exception has occurred", __FILE__, __LINE__, __FUNCTION__);
415 ZLOG_ERROR( zerr.printErrorLog() );
416 return 0;
417 }
418 catch(const ZErrorMessage& etype)
419 {
420 ZLOG_ERROR( etype.printErrorLog() );
421 return 0;
422 }
423
424 return 1;
425 }

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