# -*- coding: utf-8 -*-
"""
Copyright (c) 2015 Computational Biomechanics (CoBi) Core, Department of
Biomedical Engineering, Cleveland Clinic

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
-------------------

SpringStiffness.py

DESCRIPTION:

Python script first changes all of the springs to type = "tension-only linear." Next the script will
find the manually added springs in an .feb file due to their stiffness equaling zero. It will then
keep a count of the number of springs equal to zero. After the user specifies the stiffness value they
would like distributed across the springs, it will divide that value by the count (number of springs)
and set each of the springs who were originally zero to that value, not affecting springs who's values
were not zero in the first place. It will allow the user to then save the updated .feb file as a newly
named file. Just for reference, the scipt will report the elapsed time as well.

In order to run the script, the user simply has to be in the appropriate directory and
type 'python SpringStiffness.py'. There are no other arguments necessary.

The script will prompt the user with questions along the way to gather the
following inputs:

infile = the name to locate the desired .feb file to make changes to, the
         user does not need to include the extension at the end (e.g. infile instead of
         infile.feb)
c_stiffness = the stiffness distributed across the springs manually created by the user, just enter
              number
outfile = the desired name for the outfile.feb, which will also be given to outfile.txt (no need to
          type the extension)
         
         

The script will then result in the following outputs:

outfile.feb = the newly generated .feb file to be run in FEBio with the appropriate changes
outfile.txt = a summary of the inputs given by the user as well as the spring
              count for future reference, contained in a .txt file


REQUIREMENTS:

Python Version 2.7 (http://www.python.org)

DEVELOPERS:

Connor Lough
Computational Biomodeling (CoBi) Core
Department of Biomedical Engineering
Lerner Research Institute
Cleveland Clinic
Cleveland, OH
loughc@ccf.org
erdemira@ccf.org

########### NOTES ################

Future Development Ideas:

--> Figure out how to distinguish between springs connecting lateral mensiscus to tibia and springs
    connecting medial meniscus to tibia.

--> While the script is searching where the value for E is 0, it can also record those nodes as well, which
    may be helpfull down the road.

--> Reference for using ElementTree:
        https://docs.python.org/2/library/xml.etree.elementtree.html#finding-interesting-elements
        
--> If needed, I can set up to read a config file, so that multiple operations can be handled. The config
    file would contain the 3 outputs for each operation.

##################################

"""

# infile = 'JointCapsuleSprings.feb'
infile = raw_input('What file will be the input? ') + '.feb'
# don't need to include the extension, e.g. infile instead of infile.feb


# c_stiffness = '222'
c_stiffness = raw_input('What do you want the Young\'s Modulus (stiffness) distributed across all the springs to be?  ')

title = raw_input('What is the output file name? ')    
outfile = open(title + '.feb', 'w')
# don't need to include the extension, just the name

import time
t = time.time()

# the following will give the option to use cElementTree instead, which is faster
try:
    from xml.etree.cElementTree import cElementTree as ElementTree # preferrably load cElementTree is much faster than ElementTree
except ImportError:
    from xml.etree.ElementTree import ElementTree
# from xml.etree.ElementTree import ElementTree

tree = ElementTree()
tree.parse(infile)
root = tree.getroot()

for spring in root.iter('spring'):
   spring.set('type', 'tension-only linear')

print ' \n'
print 'Changing type to tension-only linear.'

count = 0

for E in root.iter('E'):
	try:
	  if int(E.text) == 0:
	     count = count + 1
	except: 
	  pass

print ' \n'
print 'Total number of springs with a stiffness of zero: %r' % count

count = float(count)
c_stiffness = float(c_stiffness)
individual_stiffness = str(c_stiffness/count)
tempstring = str(individual_stiffness)
print ' \n'
print 'The new individual stiffness for each spring will be: %r' % individual_stiffness

for E in root.iter('E'):
	try:
	  if int(E.text) == 0:
	     E.text = tempstring
	except: 
	  pass

# write to new .feb file
tree.write(outfile, xml_declaration=True, encoding='ISO-8859-1', method="xml")

# write specifics to .txt file
f=open(title + '.txt', 'w')
f.write('Infile = ' + infile)
f.write(' \n')
f.write('Outfile = ' + title + '.feb')
f.write(' \n')
f.write('Distributed Stiffness = ' + str(c_stiffness))
f.write(' \n')
f.write('Count = ' + str(count))
f.write(' \n')
f.write('Individual Stiffness = ' + tempstring)
f.close()

elapsed = time.time() - t

print ' \n'
print 'The changes have been made and stored in output file.'
print 'Specifics saved in .txt file.'
print 'The elapsed time of the operation was %r seconds.' % elapsed
print ' \n'

#print 'End of script.'
