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