#!/usr/bin/python

import os
from os.path import basename
import csv
import sys



#This script takes a bab tim-barrel blade as template and searches for the best pair fit of both beta strands to the target PDB.
# I assume that the blade has strands at the end and the begining.


def find_core_helix(template):
	residue={'residues':[]}
	cmd.iterate(template,'residues.append(resi)',space=residue)
	template_strands=set(residue.get('residues'))
	template_strands=list(template_strands)
	template_strands = sorted(map(int,template_strands))

	residue={'residues':[]}
	cmd.iterate(template+" and ss h",'residues.append(resi)',space=residue)
	template_helix=set(residue.get('residues'))


	current_helix_length=0
	found_helix=0
	i=len(template_strands)-1
	while not found_helix and i>0:
		#print i
		if str(template_strands[i]) in template_helix:
			current_helix_length=current_helix_length+1
			#print template_strands[i]
		elif current_helix_length>4:
			found_helix=1
		else:
			current_helix_length=0
		i=i-1
	#print "last helix residue is:"+str(template_strands[i+1])
	#print current_helix_length
	cmd.select(template+"_helix","resi %d-%d and %s and name CA+O+N+C"%(template_strands[i+2],template_strands[i+2]+current_helix_length-1,template))

	return template+"_helix"
#cmd.extend("findCorehelix", find_core_helix)

#acceptes two helices, target and template and calculates the over lap between them.returns the longest overlap ratio
# i.e if one helix is 10 aa'a long and the other is 5 and overlap is 4 then the function return 0.8
def calculate_helix_over_lap(template_helix,target_helix):
	residue={'residues':[]}
	cmd.iterate(template_helix,'residues.append(resi)',space=residue)
	template_helix_residues=set(residue.get('residues'))

	residue={'residues':[]}
	cmd.iterate(target_helix,'residues.append(resi)',space=residue)
	target_helix_residues=set(residue.get('residues'))

	cmd.select("target_helix_overlap","%s around 2 and %s"%(template_helix, target_helix))

	residue={'residues':[]}
	cmd.iterate("target_helix_overlap",'residues.append(resi)',space=residue)
	overlap_residues=set(residue.get('residues'))
#	print overlap_residues
	overlap_helix=0
	for i in overlap_residues:
		if i in target_helix_residues:
			overlap_helix+=1
	print "helix over lap:"+str(max(float(overlap_helix)/float(len(target_helix_residues)),float(overlap_helix)/float(len(template_helix_residues))))

	return max(float(overlap_helix)/float(len(target_helix_residues)),float(overlap_helix)/float(len(template_helix_residues)))

#given the tample helix (which I assume is continuous and well defined) and the target helix it defines alignmnet if the start and end of one of the helics
#is under a distnace cutoff of the other helix
def calculate_helix_alignmnet(template_helix, target_blade):
	print "bla"

# given a set of residues and a starting residue i it makes sure that the following 3 residues are i+1 i+2
def find_continues_strand(i, res_set):
	while (not(res_set[i+2]-res_set[i+1]==1) or not (res_set[i+1]-res_set[i]==1)):
		i=i+1

	#print str(res_set[i])+"-"+str(res_set[i+2])
	return i

###################################################################
########## 			MAIN 			 ##########
###################################################################

lines=[]
num_of_arg=len(sys.argv)
print num_of_arg
num=1
if os.path.isfile("pdb_file_list") :
	pdb_file_list = open("pdb_file_list", "r")
	lines = pdb_file_list.read().split('\n')
else:
	print "template"+str(sys.argv[num_of_arg-2])
	print "target"+str(sys.argv[num_of_arg-1])

	lines.append(sys.argv[num_of_arg-2])
	lines.append(sys.argv[num_of_arg-1])

# check if if -helix option is passed if so then only save pdbs with helix overlap
try:
	helix_flag=0
	helix_flag=sys.argv.index("-helix")+1
	helix_flag = int(sys.argv[helix_flag])
	if not isinstance(helix_flag , int):
		print "helix flag accepts wither 1 or 0"
		sys.exit()
except:
	pass




#load refrence structure
cmd.load(lines[0])
template=basename(lines[0])[:-4]
residue={'residues':[]}
cmd.iterate(template,'residues.append(resi)',space=residue)
template_strands=set(residue.get('residues'))
template_strands=list(template_strands)
template_strands = sorted(map(int,template_strands))
cmd.select("template_first_strand","resi %d-%d and %s and name CA+C+O+N"%(template_strands[0],template_strands[2],template))
cmd.select("template_second_strand","resi %d-%d and %s and name CA+C+O+N"%(template_strands[-3],template_strands[-1],template))

lines.pop(0) #remove template pdb file name from the list of files
best=10 #In order to avoid 2 or more matches I am also saving the top score. The result saved will be the top score
hit=1
for line in lines:
	try:
		if line !="":
			#print line
			cmd.load(line)
			target=basename(line[:-4])
			cmd.remove("het")
			cmd.select("target",target)
			#select all non strand residues on target
			residue={'residues':[]}
			cmd.iterate("target and not ss h",'residues.append(resi)',space=residue)
			target_strand=set(residue.get('residues'))
			target_strand=list(target_strand)
			target_strand = sorted(map(int,target_strand))
			#define target first strand
			set_pair_fit_value_stem_1=10000000000
			best_target_stem_1_position=0
			best_target_stem_2_position=0
			temp=0
			for j in range(0, len(target_strand)):
				for k in range(j, len(target_strand)):
					print "j is:"+str(j)+"k is:"+str(k)
					try:
						cmd.select("first_target_strand", "%s and resi %d-%d and name c+ca+n+o"%(target,target_strand[find_continues_strand(j, target_strand)],target_strand[find_continues_strand(j, target_strand)+2]))
					except:
						continue
					try:
						cmd.select("second_target_strand", "%s and resi %d-%d and name c+ca+n+o"%(target,target_strand[find_continues_strand(k, target_strand)],target_strand[find_continues_strand(k, target_strand)+2]))
					except:
						continue
					temp=cmd.pair_fit("first_target_strand + second_target_strand","template_first_strand + template_second_strand")
					try:
						# uncomment these lines to dump intermediate alignmnets						
						#print target+"_"+str(num)+".pdb"
						#cmd.save( template+"_"+str(num)+".pdb",template)
						num=num+1
					except:
						continue
					print "temp: "+str(temp)
					print "target strand first res="+str(target_strand[j])
					print "target strand second res="+str(target_strand[k])
					if (temp>0) and (temp<2) and (temp<best) :
						best=temp
					#if (temp>0) and (temp<set_pair_fit_value_stem_1) :
						print "!!!!!!!!!!!!!!!!!!!!!"
						print "helix flags is:"+str(helix_flag)
						set_pair_fit_value_stem_1=temp
						best_target_stem_1_position=target_strand[j]
						best_target_stem_2_position=target_strand[k]
						print "best_target_stem_1_position=target_strand[j]",best_target_stem_1_position
						print "best_target_stem_2_position=target_strand[k]",best_target_stem_2_position
						print "helix flags is:"+str(helix_flag)
			#print "The best pair fit score is:"+str(set_pair_fit_value_stem_1)
						cmd.select("first_target_strand", "%s and resi %d-%d and name c+ca+n+o"%(target,best_target_stem_1_position,best_target_stem_1_position+2))
						cmd.select("second_target_strand", "%s and resi %d-%d and name c+ca+n+o"%(target,best_target_stem_2_position,best_target_stem_2_position+2))
						cmd.pair_fit("first_target_strand + second_target_strand","template_first_strand + template_second_strand")
						cmd.create("blade_aligned", "%s and resi %d-%d"%(target,best_target_stem_1_position, best_target_stem_2_position+2))
						print "helix flags is:"+str(helix_flag)
#						find_core_helix(template);
#						find_core_helix("blade_aligned");
						#if helix_flag is set to true then save best alignmnet of blade else only saveif helix is above 0.8 overlap
						if helix_flag==0:
							print "SAVING!!!"
							if not os.path.isdir("pdb"):
								os.makedirs("pdb")							
							cmd.save("pdb/"+target+".pdb","blade_aligned")
							hit=hit+1



	except:
		continue
