// File: /workspace/github_cpp_makefile_star2_O2/richardposner[P]BioNetFit2/src/code/Swarm.cpp
// Function: Swarm::runAGA()
void Swarm::runAGA() {
	if (options.verbosity >= 3) {
		cout << "Running an asynchronous genetic fit" << endl;
	}

	if (!checkIfFileExists(options.jobOutputDir + "1")) {
		string createDirCmd = "mkdir " + options.jobOutputDir + "1";
		if (runCommand(createDirCmd) != 0) {
			outputError("Error: Couldn't create first generation output directory with command: " + createDirCmd + ". Quitting.");
		}
	}

	//int sp = 0;

	// Holds finished particles
	vector<unsigned int> finishedParticles;

	// Run the first generation
	runGeneration();

	// Save swarm state
	saveSwarmState();


	string outputPath = options.jobOutputDir + toString(currentGeneration - 1 ) + "_summary.txt";

	outputRunSummary(outputPath);

	cout << "Generation: " << toString(currentGeneration - 1 ) << endl;


	// Breed generation
	breedGenerationGA();


	// Re-launch the particles in to the Swarm proper
	/*for (int p = 1; p <= options.swarmSize; ++p) {


		//for(int mid = 0; mid < options.models.size(); mid++){

		//	launchSubParticle(p, mid, false);

		//}

		launchParticle(p, false);
	}

*/

	//int newFinishedPar = 0;

	//bool stopCriteria = false;
	//int iteration = 0;

	/*
	cout << "==================================ENTERING LOOP==================================" << endl;
	while (!stopCriteria){
		usleep(250000);
		cout << "RAQUEL Iteration " << iteration;
		iteration++;
		// Check for any messages from particles and store finished particles

		//finishedParticles = checkMasterMessages();
		finishedParticles = checkMasterMessages();
		newFinishedPar += finishedParticles.size();

		cout << "new finished particles " << newFinishedPar << endl;
		cout << "Running particles " << runningParticles_.size() << endl;
		cout << "Global finished " << finishedParticles_.size() << endl;
		cout << "Global finished sub " << finishedSubParticles_.size() << endl;

		// Check stop criteria
		cout << "Checking stop criteria" << endl;
		stopCriteria = checkStopCriteria();
		cout << "Done, stop criteria value = " << stopCriteria << endl;

		cout << "flightcounter = " << flightCounter_ << endl;
		cout << "max flightcounter" << options.maxNumSimulations << endl;

		// Cleanup old files if needed
		string currentDirectory = options.jobOutputDir + toString(currentGeneration);
		if (options.deleteOldFiles) {
			cleanupFiles(currentDirectory.c_str());
		}

		// If we haven't reached stop criteria, breed and re-launch finished particles
//		if (!stopCriteria && finishedParticles.size() >= options.swarmSize/2) {
		if (!stopCriteria && finishedParticles_.size() >= options.swarmSize/2) {
			cout << "RAQUEL preparing for asynchronous breed, 1/2 of particles are done" << endl;
			// Get new params for any finished particles
			//breedGenerationGA(finishedParticles);
			copy(finishedParticles_.begin(), finishedParticles_.end(), inserter(finishedParticles, finishedParticles.begin()));
			cout << "Async Particles done: " << finishedParticles.size() << endl;

			breedGenerationGA(finishedParticles);
			newFinishedPar = 0;

		//for(auto i = finishedParticles.begin(); i != finishedParticles.end(); ++i){
		//		for(int j=0; j < options.models.size(); j++){
		//			sp = fcalcsubParID(*i, j, options.models.size());
		//			cout << "sending nex gen to " << sp << endl;
		//			swarmComm->sendToSwarm(0, sp, NEXT_GENERATION, false, swarmComm->univMessageSender);
		//		}
		//	}
			//finishedParticles.clear();
			//finishedParticles_.clear();
			//finishedSubParticles_.clear(); //Raquel added to solve problem of less and less result files as generations go

			// Re-launch any finished particles
			for (auto pID = finishedParticles_.begin(); pID != finishedParticles_.end(); ++pID) {

				launchParticle(*pID, false);

			}

			currentGeneration++;
			flightCounter_++;



		}
	}
	*/
	bool stopCriteria = false;
	while (!stopCriteria){
		if (options.verbosity >= 4) {
			cout << "RAQUEL: Started runGeneration();" << endl;
		}
		runAsyncGeneration();
		if (options.verbosity >= 4) {
			cout << "RAQUEL: Finished runGeneration();" << endl;

			cout << "RAQUEL: Started checkStopCriteria();" << endl;
		}

		saveSwarmState();
		if (options.verbosity >= 4) {
			cout << "RAQUEL: Finished saveSwarmState();" << endl;
		}


		string currentDirectory = options.jobOutputDir + toString(currentGeneration);
		if (options.deleteOldFiles) {
			if (options.verbosity >= 4) {
				cout << "RAQUEL: Started cleanupFiles();" << endl;
			}
			cleanupFiles(currentDirectory.c_str());
			if (options.verbosity >= 4) {
				cout << "RAQUEL: Finished cleanupFiles();" << endl;
			}

		}

		string outputPath = options.jobOutputDir + toString(currentGeneration - 1 ) + "_summary.txt";

		outputRunSummary(outputPath);

		cout << "Generation: " << toString(currentGeneration - 1 ) << endl;

		stopCriteria = checkStopCriteria();
		if (options.verbosity >= 4) {
			cout << "RAQUEL: Stop criteria value is " << stopCriteria << endl;

			cout << "RAQUEL: Finished checkStopCriteria();" << endl;
			cout << "RAQUEL: Started saveSwarmState();" << endl;
		}

		if (!stopCriteria) {

			if(options.verbosity>=3){

				cout << "RAQUEL: started breedGenerationGA();" << endl;
			}
			finishedParticles.clear();
			for(auto i = finishedParticles_.begin(); i!=finishedParticles_.end(); ++i){
				//cout << "RAQUEL: processing particle number: " << *i << endl;
				finishedParticles.push_back(*i);
			}
			breedGenerationGA(finishedParticles);
			if(options.verbosity>=3){

				cout << "RAQUEL: finished breedGenerationGA();" << endl;
			}
		}

		currentsubswarmBestFits_.clear();

	}

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1a8, %rsp            # imm = 0x1A8
movq %rdi, %rbx
cmpl $0x3, 0x1614(%rdi)
jb 0x6f7ac
movq 0xf6800(%rip), %rdi     # 0x165f98
leaq 0x6f2fb(%rip), %rsi     # 0xdea9a
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
leaq 0x1520(%rbx), %rsi
leaq 0x70bf1(%rip), %rdx     # 0xe03ab
leaq 0x188(%rsp), %r14
movq %r14, %rdi
movq %rsi, (%rsp)
callq 0x334ed
movq %r14, %rdi
callq 0x9ec28
movl %eax, %ebp
leaq 0x188(%rsp), %rdi
callq 0x295a0
testl %ebp, %ebp
jne 0x6f85f
leaq 0x666a7(%rip), %rsi     # 0xd5e97
leaq 0x8(%rsp), %r14
movq %r14, %rdi
movq (%rsp), %rdx
callq 0x3338b
leaq 0x70ba3(%rip), %rdx     # 0xe03ab
leaq 0x50(%rsp), %rdi
movq %r14, %rsi
callq 0x3336c
leaq 0x8(%rsp), %rdi
callq 0x295a0
leaq 0xe8(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x28dd0
leaq 0xe8(%rsp), %rdi
callq 0x9f543
movl %eax, %ebp
leaq 0xe8(%rsp), %rdi
callq 0x295a0
testl %ebp, %ebp
jne 0x6fcea
leaq 0x50(%rsp), %rdi
callq 0x295a0
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
andq $0x0, 0x40(%rsp)
movq %rbx, %rdi
callq 0x76bce
movq %rbx, %rdi
callq 0x7ec70
movl 0x13e8(%rbx), %esi
decl %esi
leaq 0x70(%rsp), %rdi
callq 0x9f56b
leaq 0x8(%rsp), %rdi
leaq 0x70(%rsp), %rdx
movq (%rsp), %rsi
callq 0x5a115
leaq 0x6f09d(%rip), %rdx     # 0xde946
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x3336c
leaq 0x8(%rsp), %rdi
callq 0x295a0
leaq 0x70(%rsp), %rdi
callq 0x295a0
leaq 0xc8(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x28dd0
leaq 0xc8(%rsp), %rsi
movq %rbx, %rdi
callq 0x7942a
leaq 0xc8(%rsp), %rdi
callq 0x295a0
movq 0xf6696(%rip), %rdi     # 0x165f98
leaq 0x6dbb9(%rip), %rsi     # 0xdd4c2
callq 0x289f0
movq %rax, %r14
movl 0x13e8(%rbx), %esi
decl %esi
leaq 0x8(%rsp), %rdi
callq 0x9f56b
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x28910
movq %rax, %rdi
callq 0x284a0
leaq 0x8(%rsp), %rdi
callq 0x295a0
xorps %xmm0, %xmm0
leaq 0x90(%rsp), %rsi
movaps %xmm0, (%rsi)
andq $0x0, 0x10(%rsi)
movq %rbx, %rdi
callq 0x7f610
leaq 0x90(%rsp), %rdi
callq 0x5b268
leaq 0x18c8(%rbx), %r12
leaq 0x1c30(%rbx), %rax
movq %rax, 0x28(%rsp)
leaq 0x70(%rsp), %r13
leaq 0x148(%rsp), %r15
leaq 0x30(%rsp), %rbp
cmpl $0x4, 0x1614(%rbx)
jb 0x6f9b3
movq 0xf65f9(%rip), %rdi     # 0x165f98
leaq 0x6f118(%rip), %rsi     # 0xdeabe
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
movq %rbx, %rdi
callq 0x78478
cmpl $0x4, 0x1614(%rbx)
jb 0x6f9fa
movq 0xf65cd(%rip), %rdi     # 0x165f98
leaq 0x6f10d(%rip), %rsi     # 0xdeadf
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
movq 0xf65b2(%rip), %rdi     # 0x165f98
leaq 0x6f114(%rip), %rsi     # 0xdeb01
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
movq %rbx, %rdi
callq 0x7ec70
cmpl $0x4, 0x1614(%rbx)
jb 0x6fa26
movq 0xf6586(%rip), %rdi     # 0x165f98
leaq 0x6f10d(%rip), %rsi     # 0xdeb26
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
movl 0x13e8(%rbx), %esi
movq %r13, %rdi
callq 0x9f56b
leaq 0x8(%rsp), %rdi
movq (%rsp), %rsi
movq %r13, %rdx
callq 0x5a115
movq %r13, %rdi
callq 0x295a0
cmpb $0x1, 0x1646(%rbx)
jne 0x6faa8
cmpl $0x4, 0x1614(%rbx)
jb 0x6fa7a
movq 0xf6532(%rip), %rdi     # 0x165f98
leaq 0x6f0dc(%rip), %rsi     # 0xdeb49
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
movq 0x8(%rsp), %rsi
callq 0x791e0
cmpl $0x4, 0x1614(%rbx)
jb 0x6faa8
movq 0xf6504(%rip), %rdi     # 0x165f98
leaq 0x6f0ce(%rip), %rsi     # 0xdeb69
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
movl 0x13e8(%rbx), %esi
decl %esi
leaq 0x128(%rsp), %r14
movq %r14, %rdi
callq 0x9f56b
movq %r15, %rdi
movq (%rsp), %rsi
movq %r14, %rdx
callq 0x5a115
movq %r13, %rdi
movq %r15, %rsi
leaq 0x6ee6a(%rip), %rdx     # 0xde946
callq 0x3336c
movq %r15, %rdi
callq 0x295a0
leaq 0x128(%rsp), %rdi
callq 0x295a0
leaq 0x108(%rsp), %rdi
movq %r13, %rsi
callq 0x28dd0
movq %rbx, %rdi
leaq 0x108(%rsp), %r14
movq %r14, %rsi
callq 0x7942a
movq %r14, %rdi
callq 0x295a0
movq 0xf6470(%rip), %rdi     # 0x165f98
leaq 0x6d993(%rip), %rsi     # 0xdd4c2
callq 0x289f0
movq %rax, %r14
movl 0x13e8(%rbx), %esi
decl %esi
movq %r15, %rdi
callq 0x9f56b
movq %r14, %rdi
movq %r15, %rsi
callq 0x28910
movq %rax, %rdi
callq 0x284a0
movq %r15, %rdi
callq 0x295a0
movq %rbx, %rdi
callq 0x72f2a
movl %eax, %r14d
cmpl $0x4, 0x1614(%rbx)
jb 0x6fbd3
movq 0xf641b(%rip), %rdi     # 0x165f98
leaq 0x6f006(%rip), %rsi     # 0xdeb8a
callq 0x289f0
movzbl %r14b, %esi
movq %rax, %rdi
callq 0x29180
movq %rax, %rdi
callq 0x284a0
movq 0xf63f4(%rip), %rdi     # 0x165f98
leaq 0x6efff(%rip), %rsi     # 0xdebaa
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
movq 0xf63d9(%rip), %rdi     # 0x165f98
leaq 0x6f00a(%rip), %rsi     # 0xdebd0
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
testb %r14b, %r14b
jne 0x6fca6
cmpl $0x3, 0x1614(%rbx)
jb 0x6fc00
movq 0xf63ac(%rip), %rdi     # 0x165f98
leaq 0x6efff(%rip), %rsi     # 0xdebf2
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
movq 0x30(%rsp), %rax
cmpq %rax, 0x38(%rsp)
je 0x6fc11
movq %rax, 0x38(%rsp)
movq 0x18d8(%rbx), %r14
cmpq %r12, %r14
je 0x6fc36
leaq 0x20(%r14), %rsi
movq %rbp, %rdi
callq 0x5a59e
movq %r14, %rdi
callq 0x28b60
movq %rax, %r14
jmp 0x6fc18
leaq 0xb0(%rsp), %rdi
movq %rbp, %rsi
callq 0x8673e
movq %rbx, %rdi
leaq 0xb0(%rsp), %r14
movq %r14, %rsi
callq 0x7f610
movq %r14, %rdi
callq 0x5b268
cmpl $0x3, 0x1614(%rbx)
jb 0x6fc85
movq 0xf6327(%rip), %rdi     # 0x165f98
leaq 0x6ef9f(%rip), %rsi     # 0xdec17
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
movq 0x28(%rsp), %rdi
callq 0x8f982
movq %r13, %rdi
callq 0x295a0
leaq 0x8(%rsp), %rdi
callq 0x295a0
jmp 0x6f98f
movq 0x28(%rsp), %rdi
callq 0x8f982
leaq 0x70(%rsp), %rdi
callq 0x295a0
leaq 0x8(%rsp), %rdi
callq 0x295a0
leaq 0x50(%rsp), %rdi
callq 0x295a0
leaq 0x30(%rsp), %rdi
callq 0x5b268
addq $0x1a8, %rsp            # imm = 0x1A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x6ec0d(%rip), %rsi     # 0xde8fe
leaq 0x8(%rsp), %rdi
leaq 0x50(%rsp), %rdx
callq 0x3338b
leaq 0x6fe9b(%rip), %rdx     # 0xdfba2
leaq 0x168(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x3336c
leaq 0x168(%rsp), %rsi
movq %rbx, %rdi
callq 0x6aed2
movq %rax, %rbx
leaq 0x168(%rsp), %rdi
callq 0x295a0
jmp 0x6fd3e
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
jmp 0x6fd52
jmp 0x6fd59
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0x295a0
jmp 0x6fd5c
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
jmp 0x6fdc0
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
jmp 0x6fdc0
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x5b268
jmp 0x6fe59
jmp 0x6fe3b
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
jmp 0x6fe54
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x295a0
jmp 0x6fda9
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
jmp 0x6fe5e
jmp 0x6fdce
movq %rax, %rbx
leaq 0x188(%rsp), %rdi
callq 0x295a0
jmp 0x6fe6d
jmp 0x6fe24
jmp 0x6fe3b
movq %rax, %rbx
jmp 0x6fe63
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
callq 0x5b268
jmp 0x6fe45
jmp 0x6fe3b
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
jmp 0x6fe54
jmp 0x6fe24
movq %rax, %rbx
jmp 0x6fe0b
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
callq 0x295a0
leaq 0x128(%rsp), %rdi
jmp 0x6fe4a
movq %rax, %rbx
leaq 0x108(%rsp), %rdi
jmp 0x6fe34
jmp 0x6fe42
movq %rax, %rbx
jmp 0x6fe4f
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
callq 0x295a0
jmp 0x6fe45
movq %rax, %rbx
jmp 0x6fe59
jmp 0x6fe42
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x295a0
leaq 0x8(%rsp), %rdi
callq 0x295a0
leaq 0x50(%rsp), %rdi
callq 0x295a0
leaq 0x30(%rsp), %rdi
callq 0x5b268
movq %rbx, %rdi
callq 0x292f0
nop