bioem.cpp 25.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <fstream>
#include <boost/program_options.hpp>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <cmath>
#include <omp.h>

#include <fftw3.h>
#include <math.h>
#include "cmodules/timer.h"

#include "param.h"
#include "bioem.h"
#include "model.h"
#include "map.h"


#include "bioem_algorithm.h"


using namespace boost;
namespace po = boost::program_options;

using namespace std;

// A helper function of Boost
template<class T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
34
35
	copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
	return os;
36
37
38
39
}

bioem::bioem()
{
40
	FFTAlgo = getenv("FFTALGO") == NULL ? 0 : atoi(getenv("FFTALGO"));
41
42
43
44
}

bioem::~bioem()
{
David Rohr's avatar
David Rohr committed
45

46
47
48
49
}

int bioem::configure(int ac, char* av[])
{
50
51
52
53
54
55
56
57
58
59
	/**************************************************************************************/
	/**** Configuration Routine using boost for extracting parameters, models and maps ****/
	/**************************************************************************************/
	/****** And Precalculating necessary grids, map crosscorrelations and kernels  ********/
	/*************************************************************************************/

	/*** Inizialzing default variables ***/
	std::string infile,modelfile,mapfile;
	Model.readPDB=false;
	param.writeAngles=false;
60
61
62
	RefMap.dumpMap = false;
	RefMap.loadMap = false;

63
64
65
	/*************************************************************************************/
	cout << " ++++++++++++ FROM COMMAND LINE +++++++++++\n\n";
	/*************************************************************************************/
66

67
	/********************* Command line reading input with BOOST ************************/
68

69
70
71
72
73
74
75
	try {
		po::options_description desc("Command line inputs");
		desc.add_options()
		("Inputfile", po::value<std::string>(), "Name of input parameter file")
		("Modelfile", po::value< std::string>() , "Name of model file")
		("Particlesfile", po::value< std::string>(), "Name of paricles file")
		("ReadPDB", "(Optional) If reading model file in PDB format")
76
77
		("DumpMaps", "(Optional) Dump maps after they were red from maps file")
		("LoadMapDump", "(Optional) Read Maps from dump instead of maps file")
78
79
80
81
82
83
84
85
		("help", "(Optional) Produce help message")
		;

		po::positional_options_description p;
		p.add("Inputfile", -1);
		p.add("Modelfile", -1);
		p.add("Particlesfile", -1);
		p.add("ReadPDB", -1);
86
87
88
		p.add("DumpMaps", -1);
		p.add("LoadMapDump", -1);

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
		po::variables_map vm;
		po::store(po::command_line_parser(ac, av).
				  options(desc).positional(p).run(), vm);
		po::notify(vm);

		if((ac < 6)) {
			std::cout << desc << std::endl;
			return 0;
		}
		if (vm.count("help")) {
			cout << "Usage: options_description [options]\n";
			cout << desc;
			return 0;
		}

		if (vm.count("Inputfile"))
		{
			cout << "Input file is: ";
			cout << vm["Inputfile"].as< std::string >()<< "\n";
			infile=vm["Inputfile"].as< std::string >();
		}
		if (vm.count("Modelfile"))
		{
			cout << "Model file is: "
				 << vm["Modelfile"].as<  std::string  >() << "\n";
			modelfile=vm["Modelfile"].as<  std::string  >();
		}

		if (vm.count("ReadPDB"))
		{
			cout << "Reading model file in PDB format.\n";
			Model.readPDB=true;
		}

		if (vm.count("DumpMaps"))
		{
			cout << "Dumping Maps after reading from file.\n";
			RefMap.dumpMap = true;
		}

		if (vm.count("LoadMapDump"))
		{
			cout << "Loading Map dump.\n";
			RefMap.loadMap = true;
		}

		if (vm.count("Particlesfile"))
		{
			cout << "Paricle file is: "
				 << vm["Particlesfile"].as< std::string >() << "\n";
			mapfile=vm["Particlesfile"].as< std::string >();
		}
	}
	catch(std::exception& e)
	{
		cout << e.what() << "\n";
		return 1;
	}

	/********************* Reading Parameter Input ***************************/
	// copying inputfile to param class
	param.fileinput = infile.c_str();
	param.readParameters();

	/********************* Reading Model Input ******************************/
	// copying modelfile to model class
	Model.filemodel = modelfile.c_str();
	Model.readModel();

	/********************* Reading Particle Maps Input **********************/
	/********* HERE: PROBLEM if maps dont fit on the memory!! ***************/
	// copying mapfile to ref map class
	RefMap.filemap = mapfile.c_str();
	RefMap.readRefMaps(param);

	/****************** Precalculating Necessary Stuff *********************/
	precalculate();
David Rohr's avatar
David Rohr committed
166

167
168
169
170
171
	if (getenv("BIOEM_DEBUG_BREAK"))
	{
		param.nTotGridAngles = atoi(getenv("BIOEM_DEBUG_BREAK"));
		param.nTotCTFs = atoi(getenv("BIOEM_DEBUG_BREAK"));
	}
David Rohr's avatar
David Rohr committed
172

173
174
	deviceInit();

175
	return(0);
176
177
178
179
}

int bioem::precalculate()
{
180
181
182
	/**************************************************************************************/
	/* Precalculating Routine of Orientation grids, Map crosscorrelations and CTF Kernels */
	/**************************************************************************************/
183

184
185
	// Generating Grids of orientations
	param.CalculateGridsParam();
186

187
188
189
190
191
192
193
194
195
196
	myfloat_t sum,sumsquare;

	//Precalculating cross-correlations of maps
	for (int iRefMap = 0; iRefMap < RefMap.ntotRefMap ; iRefMap++)
	{
		calcross_cor(RefMap.Ref[iRefMap],sum,sumsquare);
		//Storing Crosscorrelations in Map class
		RefMap.sum_RefMap[iRefMap]=sum;
		RefMap.sumsquare_RefMap[iRefMap]=sumsquare;
	}
197

198
199
	// Precalculating CTF Kernels stored in class Param
	param.CalculateRefCTF();
200

201
202
	// Precalculating Maps in Fourier space
	RefMap.PreCalculateMapsFFT(param);
203

204
	return(0);
205
206
207
208
209
}


int bioem::run()
{
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
	/**************************************************************************************/
	/**** Main BioEM routine, projects, convolutes and compares with Map using OpenMP ****/
	/**************************************************************************************/

	/**** If we want to control the number of threads -> omp_set_num_threads(XX); ******/
	/****************** Declarying class of Probability Pointer  *************************/
	pProb = new bioem_Probability[RefMap.ntotRefMap];

	printf("\tInitializing\n");
	// Inizialzing Probabilites to zero and constant to -Infinity
	for (int iRefMap = 0; iRefMap < RefMap.ntotRefMap; iRefMap ++)
	{
		pProb[iRefMap].Total=0.0;
		pProb[iRefMap].Constoadd=-9999999;
		pProb[iRefMap].max_prob=-9999999;
		for (int iOrient = 0; iOrient < param.nTotGridAngles; iOrient ++)
226
		{
227
228
229
230
231
			pProb[iRefMap].forAngles[iOrient]=0.0;
			pProb[iRefMap].ConstAngle[iOrient]=-99999999;
		}
	}
	/**************************************************************************************/
232
233
	deviceStartRun();

234
	/******************************** MAIN CYCLE ******************************************/
David Rohr's avatar
David Rohr committed
235

236
237
238
239
240
	/*** Declaring Private variables for each thread *****/
	mycomplex_t* proj_mapFFT;
	bioem_map conv_map;
	mycomplex_t* conv_mapFFT;
	myfloat_t sumCONV,sumsquareCONV;
241
242

	//allocating fftw_complex vector
243
244
	proj_mapFFT= (mycomplex_t *) myfftw_malloc(sizeof(mycomplex_t) * param.param_device.NumberPixels*param.param_device.NumberFFTPixels1D);
	conv_mapFFT= (mycomplex_t *) myfftw_malloc(sizeof(mycomplex_t) * param.param_device.NumberPixels*param.param_device.NumberFFTPixels1D);
245
246
247
248
249

	HighResTimer timer;

	printf("\tMain Loop (GridAngles %d, CTFs %d, RefMaps %d, Shifts (%d/%d)²), Pixels %d²\n", param.nTotGridAngles, param.nTotCTFs, RefMap.ntotRefMap, 2 * param.param_device.maxDisplaceCenter + param.param_device.GridSpaceCenter, param.param_device.GridSpaceCenter, param.param_device.NumberPixels);
	printf("\tInner Loop Count (%d %d %d) %lld\n", param.param_device.maxDisplaceCenter, param.param_device.GridSpaceCenter, param.param_device.NumberPixels, (long long int) (param.param_device.NumberPixels * param.param_device.NumberPixels * (2 * param.param_device.maxDisplaceCenter / param.param_device.GridSpaceCenter + 1) * (2 * param.param_device.maxDisplaceCenter / param.param_device.GridSpaceCenter + 1)));
250
251
252
253
	for (int iProjectionOut = 0; iProjectionOut < param.nTotGridAngles; iProjectionOut++)
	{
		/***************************************************************************************/
		/***** Creating Projection for given orientation and transforming to Fourier space *****/
254
		timer.ResetStart();
255
		createProjection(iProjectionOut, proj_mapFFT);
256
257
		printf("Time Projection %d: %f\n", iProjectionOut, timer.GetCurrentElapsedTime());

258
259
260
261
		/***************************************************************************************/
		/***** **** Internal Loop over convolutions **** *****/
		for (int iConv = 0; iConv < param.nTotCTFs; iConv++)
		{
262
			printf("\t\tConvolution %d %d\n", iProjectionOut, iConv);
263
264
			/*** Calculating convolutions of projection map and crosscorrelations ***/

265
			timer.ResetStart();
266
			createConvolutedProjectionMap(iProjectionOut,iConv,proj_mapFFT,conv_map,conv_mapFFT,sumCONV,sumsquareCONV);
267
268
			printf("Time Convolution %d %d: %f\n", iProjectionOut, iConv, timer.GetCurrentElapsedTime());

269
270
			/***************************************************************************************/
			/*** Comparing each calculated convoluted map with all experimental maps ***/
271
			timer.ResetStart();
272
273
274
275
276
277
278
279
280
			if (FFTAlgo == 0)
			{
				compareRefMaps(iProjectionOut, iConv, conv_map);
			}
			else
			{
				compareRefMaps2(iProjectionOut, iConv,conv_mapFFT,sumCONV,sumsquareCONV);
			}

281
282
283
			const double compTime = timer.GetCurrentElapsedTime();
			const int nShifts = 2 * param.param_device.maxDisplaceCenter / param.param_device.GridSpaceCenter + 1;
			const double nFlops = (double) RefMap.ntotRefMap * (double) nShifts * (double) nShifts *
284
								  (((double) param.param_device.NumberPixels - (double) param.param_device.maxDisplaceCenter / 2.) * ((double) param.param_device.NumberPixels - (double) param.param_device.maxDisplaceCenter / 2.) * 5. + 25.) / compTime;
285
			const double nGBs = (double) RefMap.ntotRefMap * (double) nShifts * (double) nShifts *
286
								(((double) param.param_device.NumberPixels - (double) param.param_device.maxDisplaceCenter / 2.) * ((double) param.param_device.NumberPixels - (double) param.param_device.maxDisplaceCenter / 2.) * 2. + 8.) * (double) sizeof(myfloat_t) / compTime;
287
288
289
			const double nGBs2 = (double) RefMap.ntotRefMap * ((double) param.param_device.NumberPixels * (double) param.param_device.NumberPixels + 8.) * (double) sizeof(myfloat_t) / compTime;

			printf("Time Comparison %d %d: %f sec (%f GFlops, %f GB/s (cached), %f GB/s)\n", iProjectionOut, iConv, compTime, nFlops / 1000000000., nGBs / 1000000000., nGBs2 / 1000000000.);
290
291
292
293
294
		}
	}
	//deallocating fftw_complex vector
	myfftw_free(proj_mapFFT);
	myfftw_free(conv_mapFFT);
David Rohr's avatar
David Rohr committed
295

296
297
	deviceFinishRun();

298
	/************* Writing Out Probabilities ***************/
299

300
	/*** Angular Probability ***/
301

302
303
304
305
	// if(param.writeAngles){
	ofstream angProbfile;
	angProbfile.open ("ANG_PROB_iRefMap");
	// }
306

307
308
	ofstream outputProbFile;
	outputProbFile.open ("Output_Probabilities");
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
	for (int iRefMap = 0; iRefMap < RefMap.ntotRefMap; iRefMap ++)
	{
		/**** Total Probability ***/
		outputProbFile << "RefMap " << iRefMap << " Probability  "  << log(pProb[iRefMap].Total)+pProb[iRefMap].Constoadd+0.5*log(M_PI)+(1-param.param_device.Ntotpi*0.5)*(log(2*M_PI)+1)+log(param.param_device.volu) << " Constant " << pProb[iRefMap].Constoadd  << "\n";

		outputProbFile << "RefMap " << iRefMap << " Maximizing Param: ";

		/*** Param that maximize probability****/
		outputProbFile << (pProb[iRefMap].max_prob + 0.5 * log(M_PI) + (1 - param.param_device.Ntotpi * 0.5) * (log(2 * M_PI) + 1) + log(param.param_device.volu)) << " ";
		outputProbFile << param.angles[pProb[iRefMap].max_prob_orient].pos[0] << " ";
		outputProbFile << param.angles[pProb[iRefMap].max_prob_orient].pos[1] << " ";
		outputProbFile << param.angles[pProb[iRefMap].max_prob_orient].pos[2] << " ";
		outputProbFile << param.CtfParam[pProb[iRefMap].max_prob_conv].pos[0] << " ";
		outputProbFile << param.CtfParam[pProb[iRefMap].max_prob_conv].pos[1] << " ";
		outputProbFile << param.CtfParam[pProb[iRefMap].max_prob_conv].pos[2] << " ";
325
326
		outputProbFile << pProb[iRefMap].max_prob_cent_x << " ";
		outputProbFile << pProb[iRefMap].max_prob_cent_y;
327
		outputProbFile << "\n";
328

329
		/*** For individual files***/ //angProbfile.open ("ANG_PROB_"iRefMap);
330

331
		if(param.writeAngles)
332
		{
333
334
335
			for (int iProjectionOut = 0; iProjectionOut < param.nTotGridAngles; iProjectionOut++)
			{
				angProbfile << " " << iRefMap << " " << param.angles[iProjectionOut].pos[0] << " " << param.angles[iProjectionOut].pos[1] << " " << param.angles[iProjectionOut].pos[2] << " " << log(pProb[iRefMap].forAngles[iProjectionOut])+pProb[iRefMap].ConstAngle[iProjectionOut]+0.5*log(M_PI)+(1-param.param_device.Ntotpi*0.5)*(log(2*M_PI)+1)+log(param.param_device.volu) << " " << log(param.param_device.volu) << "\n";
336

337
338
339
			}
		}
	}
340

341
342
	angProbfile.close();
	outputProbFile.close();
343

344
	//Deleting allocated pointers
345

346
347
348
349
350
351
352
353
354
355
356
	if (pProb)
	{
		delete[] pProb;
		pProb = NULL;
	}

	if (param.refCTF)
	{
		delete[] param.refCTF;
		param.refCTF =NULL;
	}
357

358
359
360
361
362
363
	if(RefMap.RefMapFFT)
	{
		delete[] RefMap.RefMapFFT;
		RefMap.RefMapFFT = NULL;
	}
	return(0);
364
365
}

366
int bioem::compareRefMaps(int iProjectionOut, int iConv, const bioem_map& conv_map, const int startMap)
367
{
368
#pragma omp parallel for
369
370
371
372
373
	for (int iRefMap = startMap; iRefMap < RefMap.ntotRefMap; iRefMap ++)
	{
		compareRefMapShifted<-1>(iRefMap,iProjectionOut,iConv,conv_map, pProb, param.param_device, RefMap);
	}
	return(0);
374
375
}

376
int bioem::compareRefMaps2(int iOrient, int iConv, mycomplex_t* localConvFFT,myfloat_t sumC,myfloat_t sumsquareC)
377
{
378
#pragma omp parallel
379
	{
380
381
382
383
		mycomplex_t *localCCT;
		myfloat_t *lCC;
		localCCT= (mycomplex_t *) myfftw_malloc(sizeof(mycomplex_t) *param.param_device.NumberPixels*param.param_device.NumberFFTPixels1D);
		lCC= (myfloat_t *) myfftw_malloc(sizeof(myfloat_t) *param.param_device.NumberPixels*param.param_device.NumberPixels);
384

385
386
387
388
389
390
391
		const int num_threads = omp_get_num_threads();
		const int thread_id = omp_get_thread_num();
		const int mapsPerThread = (RefMap.ntotRefMap + num_threads - 1) / num_threads;
		const int iStart = thread_id * mapsPerThread;
		const int iEnd = min(RefMap.ntotRefMap, (thread_id + 1) * mapsPerThread);

		for (int iRefMap = iStart; iRefMap < iEnd; iRefMap ++)
392
		{
393
			calculateCCFFT(iRefMap,iOrient, iConv, sumC,sumsquareC, localConvFFT, localCCT,lCC);
394
395
396
397
		}
		myfftw_free(localCCT);
		myfftw_free(lCC);
	}
398

399
400
401
402
	return(0);
}

/////////////NEW ROUTINE ////////////////
403
inline int bioem::calculateCCFFT(int iRefMap, int iOrient, int iConv, myfloat_t sumC,myfloat_t sumsquareC, mycomplex_t* localConvFFT,mycomplex_t* localCCT,myfloat_t* lCC)
404
{
405
	for(int i = 0;i < param.param_device.NumberPixels * param.param_device.NumberFFTPixels1D;i++)
406
	{
407
408
		localCCT[i][0] = localConvFFT[i][0] * RefMap.RefMapFFT[iRefMap].cpoints[i][0] + localConvFFT[i][1] * RefMap.RefMapFFT[iRefMap].cpoints[i][1];
		localCCT[i][1] = localConvFFT[i][1] * RefMap.RefMapFFT[iRefMap].cpoints[i][0] - localConvFFT[i][0] * RefMap.RefMapFFT[iRefMap].cpoints[i][1];
409
410
	}

411
	myfftw_execute_dft_c2r(param.fft_plan_c2r_backward,localCCT,lCC);
412
413
414
415
416
417

// Storing CORRELATIONS FOR CORRESPONDING DISPLACEMENTS & Normalizing after Backward FFT
	for (int cent_x = 0; cent_x <= param.param_device.maxDisplaceCenter; cent_x=cent_x+param.param_device.GridSpaceCenter)
	{
		for (int cent_y = 0; cent_y <= param.param_device.maxDisplaceCenter; cent_y=cent_y+param.param_device.GridSpaceCenter)
		{
418
			calProb(iRefMap, iOrient, iConv, sumC, sumsquareC, (myfloat_t) lCC[cent_x*param.param_device.NumberPixels+cent_y]/ (myfloat_t) (param.param_device.NumberPixels * param.param_device.NumberPixels), cent_x, cent_y);
419
420
421
		}
		for (int cent_y = param.param_device.NumberPixels-param.param_device.maxDisplaceCenter; cent_y < param.param_device.NumberPixels; cent_y=cent_y+param.param_device.GridSpaceCenter)
		{
422
			calProb(iRefMap, iOrient, iConv, sumC, sumsquareC, (myfloat_t) lCC[cent_x*param.param_device.NumberPixels+cent_y]/ (myfloat_t) (param.param_device.NumberPixels*param.param_device.NumberPixels), cent_x, param.param_device.NumberPixels-cent_y);
423
424
425
426
427
428
		}
	}
	for (int cent_x = param.param_device.NumberPixels-param.param_device.maxDisplaceCenter; cent_x < param.param_device.NumberPixels; cent_x=cent_x+param.param_device.GridSpaceCenter)
	{
		for (int cent_y = 0; cent_y < param.param_device.maxDisplaceCenter; cent_y=cent_y+param.param_device.GridSpaceCenter)
		{
429
			calProb(iRefMap, iOrient, iConv, sumC, sumsquareC, (myfloat_t) lCC[cent_x*param.param_device.NumberPixels+cent_y]/ (myfloat_t) (param.param_device.NumberPixels*param.param_device.NumberPixels), param.param_device.NumberPixels-cent_x, cent_y);
430
431
432
		}
		for (int cent_y = param.param_device.NumberPixels-param.param_device.maxDisplaceCenter; cent_y <= param.param_device.NumberPixels; cent_y=cent_y+param.param_device.GridSpaceCenter)
		{
433
			calProb(iRefMap, iOrient, iConv, sumC, sumsquareC, (myfloat_t) lCC[cent_x*param.param_device.NumberPixels+cent_y]/ (myfloat_t) (param.param_device.NumberPixels*param.param_device.NumberPixels), param.param_device.NumberPixels-cent_x, param.param_device.NumberPixels-cent_y);
434
435
		}
	}
436

437
438
	return (0);
}
439

440
inline int bioem::calProb(int iRefMap,int iOrient, int iConv,myfloat_t sumC,myfloat_t sumsquareC, int value, int disx, int disy)
441
{
442

443
444
445
	/********************************************************/
	/*********** Calculates the BioEM probability ***********/
	/********************************************************/
446

447
	const myfloat_t ForLogProb = (sumsquareC * param.param_device.Ntotpi - sumC * sumC);
448

449
		// Products of different cross-correlations (first element in formula)
450
451
		const myfloat_t firstele = param.param_device.Ntotpi * (RefMap.sumsquare_RefMap[iRefMap] * sumsquareC -   value * value) +
								   2 * RefMap.sum_RefMap[iRefMap] * sumC *   value - RefMap.sumsquare_RefMap[iRefMap] * sumC * sumC - RefMap.sum_RefMap[iRefMap] * RefMap.sum_RefMap[iRefMap] * sumsquareC;
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478

		//******* Calculating log of Prob*********/
		// As in fortran code: logpro=(3-Ntotpi)*0.5*log(firstele/pConvMap[iOrient].ForLogProbfromConv[iConv])+(Ntotpi*0.5-2)*log(Ntotpi-2)-0.5*log(pConvMap[iOrient].ForLogProbfromConv[iConv])+0.5*log(PI)+(1-Ntotpi*0.5)*(log(2*PI)+1);
		const myfloat_t logpro = (3 - param.param_device.Ntotpi) * 0.5 * log(firstele) + (param.param_device.Ntotpi * 0.5 - 2) * log((param.param_device.Ntotpi - 2) * ForLogProb);
//   cout << n <<" " << firstele << " "<< logpro << "\n";
		{
			/*******  Summing total Probabilities *************/
			/******* Need a constant because of numerical divergence*****/
			if(pProb[iRefMap].Constoadd < logpro)
			{
				pProb[iRefMap].Total = pProb[iRefMap].Total * exp(-logpro + pProb[iRefMap].Constoadd);
				pProb[iRefMap].Constoadd = logpro;
			}
			pProb[iRefMap].Total += exp(logpro - pProb[iRefMap].Constoadd);

			//Summing probabilities for each orientation
			if(pProb[iRefMap].ConstAngle[iOrient] < logpro)
			{
				pProb[iRefMap].forAngles[iOrient] = pProb[iRefMap].forAngles[iOrient] * exp(-logpro + pProb[iRefMap].ConstAngle[iOrient]);
				pProb[iRefMap].ConstAngle[iOrient] = logpro;
			}
			pProb[iRefMap].forAngles[iOrient] += exp(logpro - pProb[iRefMap].ConstAngle[iOrient]);

			/********** Getting parameters that maximize the probability ***********/
			if(pProb[iRefMap].max_prob < logpro)
			{
				pProb[iRefMap].max_prob = logpro;
479
480
				pProb[iRefMap].max_prob_cent_x = disx;
				pProb[iRefMap].max_prob_cent_y = disy;
481
482
483
484
485
				pProb[iRefMap].max_prob_orient = iOrient;
				pProb[iRefMap].max_prob_conv = iConv;
			}
		}
	return (0);
486
487
488
}


489
int bioem::createProjection(int iMap,mycomplex_t* mapFFT)
490
{
491
492
493
494
495
496
497
498
	/**************************************************************************************/
	/****  BioEM Create Projection routine in Euler angle predefined grid****************
	********************* and turns projection into Fourier space **********************/
	/**************************************************************************************/

	myfloat3_t RotatedPointsModel[Model.nPointsModel];
	myfloat_t rotmat[3][3];
	myfloat_t alpha, gam,beta;
499
	myfloat_t* localproj;
500

501
	localproj= (myfloat_t *) myfftw_malloc(sizeof(myfloat_t) *param.param_device.NumberPixels*param.param_device.NumberPixels);
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
	memset(localproj,0,param.param_device.NumberPixels*param.param_device.NumberPixels*sizeof(*localproj));

	alpha=param.angles[iMap].pos[0];
	beta=param.angles[iMap].pos[1];
	gam=param.angles[iMap].pos[2];

	/**** To see how things are going: cout << "Id " << omp_get_thread_num() <<  " Angs: " << alpha << " " << beta << " " << gam << "\n"; ***/

	/********** Creat Rotation with pre-defiend grid of orientations**********/

	rotmat[0][0]=cos(gam)*cos(alpha)-cos(beta)*sin(alpha)*sin(gam);
	rotmat[0][1]=cos(gam)*sin(alpha)+cos(beta)*cos(alpha)*sin(gam);
	rotmat[0][2]=sin(gam)*sin(beta);
	rotmat[1][0]=-sin(gam)*cos(alpha)-cos(beta)*sin(alpha)*cos(gam);
	rotmat[1][1]=-sin(gam)*sin(alpha)+cos(beta)*cos(alpha)*cos(gam);
	rotmat[1][2]=cos(gam)*sin(beta);
	rotmat[2][0]=sin(beta)*sin(alpha);
	rotmat[2][1]=-sin(beta)*cos(alpha);
	rotmat[2][2]=cos(beta);


	for(int n=0; n< Model.nPointsModel; n++)
	{
		RotatedPointsModel[n].pos[0]=0.0;
		RotatedPointsModel[n].pos[1]=0.0;
		RotatedPointsModel[n].pos[2]=0.0;
	}
	for(int n=0; n< Model.nPointsModel; n++)
	{
		for(int k=0; k< 3; k++)
		{
			for(int j=0; j< 3; j++)
			{
				RotatedPointsModel[n].pos[k]+=rotmat[k][j]*Model.PointsModel[n].pos[j];
			}
		}
	}

	int i, j;

	/************ Projection over the Z axis********************/
	for(int n=0; n< Model.nPointsModel; n++)
	{
		//Getting pixel that represents coordinates & shifting the start at to Numpix/2,Numpix/2 )
546
547
		i=floor(RotatedPointsModel[n].pos[0]/param.pixelSize+ (myfloat_t) param.param_device.NumberPixels / 2.0f + 0.5f);
		j=floor(RotatedPointsModel[n].pos[1]/param.pixelSize+ (myfloat_t) param.param_device.NumberPixels / 2.0f + 0.5f);
548

549
		localproj[i*param.param_device.NumberPixels+j]+=Model.densityPointsModel[n]/Model.NormDen;
550
551
552
553
554
555
556
557
558
559
560
561
	}

	/**** Output Just to check****/
	if(iMap==10)
	{
		ofstream myexamplemap;
		ofstream myexampleRot;
		myexamplemap.open ("MAP_i10");
		myexampleRot.open ("Rot_i10");
		myexamplemap << "ANGLES " << alpha << " " << beta << " " << gam << "\n";
		for(int k=0; k<param.param_device.NumberPixels; k++)
		{
562
			for(int j=0; j<param.param_device.NumberPixels; j++) myexamplemap << "\nMAP " << k << " " << j<< " " <<localproj[k*param.param_device.NumberPixels+j];
563
564
565
566
567
568
569
570
571
		}
		myexamplemap << " \n";
		for(int n=0; n< Model.nPointsModel; n++)myexampleRot << "\nCOOR " << RotatedPointsModel[n].pos[0] << " " << RotatedPointsModel[n].pos[1] << " " << RotatedPointsModel[n].pos[2];
		myexamplemap.close();
		myexampleRot.close();
	}

	/***** Converting projection to Fourier Space for Convolution later with kernel****/
	/********** Omp Critical is necessary with FFTW*******/
572
	myfftw_execute_dft_r2c(param.fft_plan_r2c_forward,localproj,mapFFT);
573
574
575
576

	return(0);
}

577
int bioem::createConvolutedProjectionMap(int iMap,int iConv,mycomplex_t* lproj,bioem_map& Mapconv, mycomplex_t* localmultFFT, myfloat_t& sumC, myfloat_t& sumsquareC)
578
579
580
581
582
583
584
{
	/**************************************************************************************/
	/****  BioEM Create Convoluted Projection Map routine, multiplies in Fourier **********
	**************** calculated Projection with convoluted precalculated Kernel**********
	*************** and Backtransforming it to real Space ******************************/
	/**************************************************************************************/

585
586
587
588
	myfloat_t* localconvFFT;
	localconvFFT= (myfloat_t *) myfftw_malloc(sizeof(myfloat_t)*param.param_device.NumberPixels*param.param_device.NumberPixels);
	mycomplex_t* tmp;
	tmp = (mycomplex_t*) myfftw_malloc(sizeof(mycomplex_t) * param.param_device.NumberPixels * param.param_device.NumberFFTPixels1D);
589
590
591

	/**** Multiplying FFTmap with corresponding kernel ****/

592
	for(int i=0;i < param.param_device.NumberPixels * param.param_device.NumberFFTPixels1D;i++)
593
	{
594
595
596
		localmultFFT[i][0] = lproj[i][0] * param.refCTF[iConv].cpoints[i][0] + lproj[i][1] * param.refCTF[iConv].cpoints[i][1];
		localmultFFT[i][1] = lproj[i][1] * param.refCTF[iConv].cpoints[i][0] - lproj[i][0] * param.refCTF[iConv].cpoints[i][1];
		// cout << "GG " << i << " " << j << " " << param.refCTF[iConv].cpoints[i][0] << " " <<param.refCTF[iConv].cpoints[i][1] <<" " <<lproj[i][0] <<" " <<lproj[i][1] << "\n";
597
598
	}

599
600
601
	//FFTW_C2R will destroy the input array, so we have to work on a copy here
	memcpy(tmp, localmultFFT, sizeof(mycomplex_t) * param.param_device.NumberPixels * param.param_device.NumberFFTPixels1D);

602
	/**** Bringing convoluted Map to real Space ****/
603
	myfftw_execute_dft_c2r(param.fft_plan_c2r_backward,tmp,localconvFFT);
604
605
606
607
608
609

	/****Asigning convolution fftw_complex to bioem_map ****/
	for(int i=0; i < param.param_device.NumberPixels ; i++ )
	{
		for(int j=0; j < param.param_device.NumberPixels ; j++ )
		{
610
			Mapconv.points[i][j]=localconvFFT[i*param.param_device.NumberPixels+j];
611
612
613
614
615
616
		}
	}

	/*** Calculating Cross-correlations of cal-convoluted map with its self *****/
	sumC=0;
	sumsquareC=0;
617
	for(int i = 0; i < param.param_device.NumberPixels * param.param_device.NumberPixels; i++)
618
	{
619
620
		sumC += localconvFFT[i];
		sumsquareC += localconvFFT[i] * localconvFFT[i];
621
622
623
	}
	/*** The DTF gives an unnormalized value so have to divded by the total number of pixels in Fourier ***/
	// Normalizing
624
625
626
627
	myfloat_t norm2 = (myfloat_t) (param.param_device.NumberPixels * param.param_device.NumberPixels);
	myfloat_t norm4 = norm2 * norm2;
	sumC = sumC / norm2;
	sumsquareC = sumsquareC / norm4;
628
629

	/**** Freeing fftw_complex created (dont know if omp critical is necessary) ****/
630
	myfftw_free(localconvFFT);
631
	myfftw_free(tmp);
632
633

	return(0);
634
635
636
637
}

int bioem::calcross_cor(bioem_map& localmap,myfloat_t& sum,myfloat_t& sumsquare)
{
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
	/*********************** Routine to calculate Cross correlations***********************/

	sum=0.0;
	sumsquare=0.0;
	for (int i = 0; i < param.param_device.NumberPixels; i++)
	{
		for (int j = 0; j < param.param_device.NumberPixels; j++)
		{
			// Calculate Sum of pixels
			sum += localmap.points[i][j];
			// Calculate Sum of pixels squared
			sumsquare += localmap.points[i][j]*localmap.points[i][j];
		}
	}
	return(0);
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
}

int bioem::deviceInit()
{
	return(0);
}

int bioem::deviceStartRun()
{
	return(0);
}

int bioem::deviceFinishRun()
{
	return(0);
}