1 /*
2 * cifo.cpp
3 *
4 * Copyright Notice: see copyright.txt
5 *
6 * Date: 3/8/2012 (D/M/Y)
7 * Author: Dmitrij Lioubartsev
8 * Email: dmitrijl42@gmail.com
9 *
10 * Main source file. Creates the classes needed for the task
11 * and calls the proper methods with some error testing.
12 */
13
14 #include <string>
15 #include <iostream>
16 #include <cctype>
17 #include <cstring>
18 #include <vector>
19 using namespace std;
20
21 #include "CifCrystal.h"
22 #include "CifParser.h"
23 #include "Config.h"
24 #include "OutputWriter.h"
25 #include "Substitution.h"
26
27 void removeFileExtension(string& fileName);
28
main(int argc,const char * argv[])29 int main(int argc, const char* argv[]) {
30
31 CifCrystal crystal = CifCrystal(); // The crystal to work with
32 CifParser parser(&crystal); //.cif file reader
33 bool stop = false;
34
35 if(argc == 1) { // no arguments given
36 stop = true;
37 cerr << "No input parameters given." << endl;
38 }
39
40 Config cfg;
41
42 if(!stop) {
43 if(argc > 2) { //config file specified
44 if(! cfg.readFile(argv[2])) {
45 cout << "WARNING: specified config file does not exist. "
46 "Using default values." << endl;
47 }
48 }
49 else {
50 //config file not specified, use default name
51 if(!cfg.readFile()) {
52 cout << "Note: no configuration file specified, but"
53 " the default \"input.cfg\" does not exist." << endl
54 << "Using default values and creating config "
55 "file with default values." << endl;
56 cfg.createConf();
57 }
58
59 }
60 }
61
62 if(!stop)
63 if(!parser.opencif(argv[1])) {
64 stop = true;
65 cerr << "File " << argv[1] << " does not exist." << endl;
66 }
67
68 if(!stop) {
69 parser.readcif();
70 bool * areSet = crystal.areSet();
71
72 if(!areSet[0]) {
73 stop = true;
74 cerr << "Could not find value for _cell_length_a "
75 "in the file " << argv[1] << ". Stopping program." << endl;
76 }
77 if(!areSet[1]) {
78 stop = true;
79 cerr << "Could not find value for _cell_length_b "
80 "in the file " << argv[1] << ". Stopping program."<< endl;
81 }
82 if(!areSet[2]) {
83 stop = true;
84 cerr << "Could not find value for _cell_length_c "
85 "in the file " << argv[1] << ". Stopping program."<< endl;
86 }
87 if(!areSet[3]) {
88 stop = true;
89 cerr << "Could not find value for _cell_angle_alpha "
90 "in the file " << argv[1] << ". Stopping program."<< endl;
91 }
92 if(!areSet[4]) {
93 stop = true;
94 cerr << "Could not find value for _cell_angle_beta "
95 "in the file " << argv[1] << ". Stopping program."<< endl;
96 }
97 if(!areSet[5]) {
98 stop = true;
99 cerr << "Could not find value for _cell_angle_gamma "
100 "in the file " << argv[1] << ". Stopping program."<< endl;
101 }
102 if(crystal.numAtoms() == 0) {
103 stop = true;
104 cerr << "Could not find any data about atoms in the file "
105 << argv[1] << ". Stopping program."<< endl;
106 }
107 if(!crystal.okData()) {
108 stop = true;
109 cerr << "Atom data in the file " << argv[1] << " is incomplete, "
110 "one or more atoms are missing some part of information "
111 "about them. Stopping program." << endl;
112 }
113
114 }
115
116 if(!stop)
117 crystal.processSymmetries();
118
119 if(!stop) {
120 crystal.makeSuperCell(cfg.getR_min());
121 cout << "Supercell formed:\t" << crystal.getDupa() << "a\t"
122 << crystal.getDupb() << "b\t" << crystal.getDupc()
123 << 'c' << endl;
124 cout.precision(2);
125 cout.setf(ios_base::fixed);
126 cout << "Final sizes: \t"
127 << crystal.getNewa() << " " << crystal.getNewb()
128 << " " << crystal.getNewc() << endl;
129 cout << "With angles: \t" << crystal.get_alpha() << " "
130 << crystal.get_beta() << " " << crystal.get_gamma()
131 << endl;
132 cout.precision(0);
133
134 crystal.makeTransformations();
135 }
136
137 string output("");
138
139 if(!stop) {
140 if(cfg.getOutput() == "default") {
141 output = argv[1];
142 } else {
143 output = cfg.getOutput();
144 }
145 }
146
147 OutputWriter writer(output);
148
149 if(!stop)
150 crystal.makeBonds();
151
152 if(!stop) {
153 Substitution sub(crystal.getAtomList(), cfg.getSubRatios(), cfg.getElims());
154 if(sub.substitute()) {
155 cout << "Total number of atoms: " << crystal.numAtoms() << endl;
156 sub.printAtomsSubstituted();
157 }
158 else
159 stop = true;
160 }
161
162 if(!stop) {
163 ForceField ff(crystal.getAtomList());
164 string ff_file = cfg.getFF_file();
165 if(ff_file == "default") {
166 ff_file = argv[1];
167 removeFileExtension(ff_file);
168 ff_file.append(".ff");
169 }
170 if(!ff.loadFromFile(ff_file)) {
171 cout << "WARNING: Could not find Force Field File "
172 << ff_file << "." << endl;
173 }
174 if(cfg.getFixCharge())
175 ff.setCharge(cfg.getCharge_tot(), crystal.getAtomList(), true);
176 else
177 ff.setCharge(cfg.getCharge_tot(), crystal.getAtomList(), false);
178 writer.createSmol(crystal);
179 }
180
181 if(!stop && cfg.getcar())
182 writer.createCar(crystal, argv[1]);
183
184 if(!stop && cfg.getxmol())
185 writer.createXmol(crystal);
186
187
188 return 0;
189 }
190
191 /*
192 * removes the file extension from the string fileName
193 */
removeFileExtension(string & fileName)194 void removeFileExtension(string& fileName) {
195 unsigned int i = fileName.length()-1;
196 while(fileName[i] != '.' && i > 0) {
197 i--;
198 }
199
200 if(i != 0) {
201 fileName.erase(i,fileName.length()-i);
202 }
203 }
204