#-------------------------------------------------------------------------------
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# 
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
# 
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
# 
# Contact Info:
# 	Bruce Donald
# 	Duke University
# 	Department of Computer Science
# 	Levine Science Research Center (LSRC)
# 	Durham
# 	NC 27708-0129 
# 	USA
# 	brd@cs.duke.edu
# 
# Copyright (C) 2011 Jeffrey W. Martin and Bruce R. Donald
# 
# <signature of Bruce Donald>, April 2011
# Bruce Donald, Professor of Computer Science
#-------------------------------------------------------------------------------


import jvm, jdshot, share
import jpype
import os.path

jdshot.getJvm().start()

import disco

OrientationCalculator = jdshot.f.disco.OrientationCalculator
ResultsReader = jdshot.f.disco.ResultsReader
ReferenceAnalyzer = jdshot.f.disco.ReferenceAnalyzer
AnnulusCalculator = jdshot.f.disco.AnnulusCalculator
SubunitVariationAnalyzer = jdshot.f.disco.SubunitVariationAnalyzer
FaceInfo = jdshot.f.disco.FaceInfo


def run( dirOut, pathInSubunit, numSubunits, pathInRdcs, pathInDistanceRestraints, pathInReference, pathInOrientations, orientationIndex, pathInMsrs, pathInVariation=None ):
	
	# load the inputs
	symmetryContext = jdshot.newSymmetryContext( jdshot.Cn, pathInSubunit, numSubunits )
	rdcsContext = jdshot.newRdcsContext( symmetryContext, pathInRdcs )
	distanceRestraintsContext = jdshot.newDistanceRestraintsContext( symmetryContext, pathInDistanceRestraints )
	reference = share.loadProtein( pathInReference )
	
	# read the orientation
	orientations = ResultsReader().readOrientations( jvm.newFile( pathInOrientations ) )
	computedOrientation = orientations.get( orientationIndex )
	print "Analyzing orientation %d of %d..." % ( orientationIndex + 1, orientations.size() )
	
	# perform normalization
	monomer = share.f.protein.Subunit( symmetryContext.getPseudoMonomer() )
	referencePosition = ReferenceAnalyzer.getSymmetryAxisPosition( reference )
	OrientationCalculator.normalizeProteinAndAxis(
		monomer,
		referencePosition,
		computedOrientation
	)
	
	# apply the variation
	if pathInVariation != None:
		variation = ResultsReader().readVariation( jvm.newFile( pathInVariation ) )
		distanceRestraintsContext.setInternalRestraints(
			SubunitVariationAnalyzer.applyVariation( variation, distanceRestraintsContext.getInternalRestraints() ),
			symmetryContext.getClonedMonomer()
		)
		print "Applied variation!"
	
	# compute the annuli
	annulusIndex = AnnulusCalculator.computeAnnuli(
		monomer,
		distanceRestraintsContext.getInternalRestraints(),
		numSubunits
	)
	
	# read the MSRs from a file
	msrs = ResultsReader().readMsrs( jvm.newFile( pathInMsrs ) )
	
	# write out the arrangement plots
	disco.writeChart(
		jvm.newFile( dirOut, "arrangementWithReference" ),
		disco.Plotter.plotArrangement( msrs, annulusIndex, False, referencePosition )
	)
	disco.writeChart(
		jvm.newFile( dirOut, "arrangementZoomedWithReference" ),
		disco.Plotter.plotArrangement( msrs, annulusIndex, True, referencePosition )
	)
	
	# TEMP
#	originalMsrs = ResultsReader().readMsrs( jvm.newFile( "/home/jeff/duke/donaldLab/workspace/jdshot/output/gb1/msrs.0.dat" ) )
#	disco.writeChart(
#		jvm.newFile( dirOut, "arrangementCompareMsrs" ),
#		disco.Plotter.plotCompareMsrs( msrs, originalMsrs, annulusIndex, False, referencePosition )
#	)
#	disco.writeChart(
#		jvm.newFile( dirOut, "arrangementCompareMsrsZoomed" ),
#		disco.Plotter.plotCompareMsrs( msrs, originalMsrs, annulusIndex, True, referencePosition )
#	)
	
	# print the min and max msr distances
	referencePosition = share.f.geom.Vector2( referencePosition.x, referencePosition.y )
	closestPosition = FaceInfo.getPointClosestTo( msrs, referencePosition )
	closestDistance = 0.0
	if closestPosition is not None:
		closestDistance = referencePosition.getDistance( closestPosition )
	farthestPosition = FaceInfo.getPointFarthestFrom( msrs, referencePosition )
	farthestDistance = referencePosition.getDistance( farthestPosition )
	
	print "Closest distance: %.3f" % closestDistance
	print "Farthest distance: %.3f" % farthestDistance
	
	print "Done!"
	

dirInput = "/home/jeff/duke/donaldLab/dshot/input"

try:

	# DAGK
#	run(
#		"output/dagk",
#		dirInput + "/2KDC.monomer.protein",
#		3,
#		dirInput + "/2KDC.experimental.rdc",
#		dirInput + "/2KDC.experimental.onlyDisulfideBonds.noe",
#		dirInput + "/2KDC.oligomer.protein",
#		"output/dagk/sampledOrientations.dat",
#		0,
#		"output/dagk/msrs.0.dat",
#		"output/dagk/variation.dat"
#	)

	# GB1
#	run(
#		"output/gb1",
#		dirInput + "/1Q10.monomer.protein",
#		2,
#		dirInput + "/1Q10.experimental.rdc",
#		dirInput + "/1Q10.experimental.fixed.noe",
#		dirInput + "/1Q10.oligomer.protein",
#		"output/gb1/sampledOrientations.dat",
#		0,
#		"output/gb1/msrs.0.dat",
#		"output/gb1/variation.dat"
#	)
	
	# GB1 reassigned
#	run(
#		"output/gb1-reassigned",
#		dirInput + "/1Q10.monomer.protein",
#		2,
#		dirInput + "/1Q10.experimental.rdc",
#		"output/gb1-reassigned/1Q10.reassigned.noe",
#		dirInput + "/1Q10.oligomer.protein",
#		"output/gb1-reassigned/sampledOrientations.dat",
#		0,
#		"output/gb1-reassigned/msrs.0.dat",
#		"output/gb1-reassigned/variation.dat"
#	)

	# GB1 no padding
	run(
		"output/gb1-noPadding",
		dirInput + "/1Q10.monomer.protein",
		2,
		dirInput + "/1Q10.experimental.rdc",
		dirInput + "/1Q10.experimental.fixed.noe",
		dirInput + "/1Q10.oligomer.protein",
		"output/gb1-noPadding/orientation.dat",
		0,
		"output/gb1-noPadding/msrs.0.dat"
	)


except jpype.JavaException as ex:
	import sys
	print >> sys.stderr, "Java Exception: %s\n" % ex
	print >> sys.stderr, ex.stacktrace()
	raise
