#Script to parse .log files generated by Fable(GrainSpotter)
#!/usr/bin/env python
from contextlib import contextmanager
import numpy as np
import sys,os


## Function to suppress unecessary output:http://thesmithfam.org/blog/2012/10/25/temporarily-suppress-console-output-in-python/
@contextmanager
def suppress_stdout():
    with open(os.devnull, "w") as devnull:
        old_stdout = sys.stdout
        sys.stdout = devnull
        try:  
            yield
        finally:
            sys.stdout = old_stdout
            
## End Output Suppression Function    

def Parser(fid):   
  NG=fid.readline() # Read First Line
  NG=NG.split()   
  NGrains=int(NG[1]) # Total number of grains found by GrainSpotter

  GL=range(1,NGrains+1,1) # List to hold Grain Numbers (For purpose of using as keys for dictionaries)
  
  # Skip next 22 lines
  with suppress_stdout():
    for i in range(22):
      print fid.readline()
        
  # Initialize Dictionaries to store data for each grain
        
  GvExMeasOM={}   # Initialize dictionary to store Gvector information
  PosDict={}
  # Initialize dictionary to store orientation matrices!
  UDict={}
  UBDict={}
  DictRdz={} # Initialize dictionary to store Rodriguez Vector
  EulerDict={}  # Initialize dictionary to store Euler Angles
  qDict={} # Initialize dictionary to store qvector information
  GvecTable={} # Initialize dictionary to store Gvector Table  

  ## Start Loop over grains from here:

  for index in range(NGrains):
    fid.readline() # Skip Line with GrainNumber, nr
    # expected gvectors #measured gvectors #measured once #measured more than once
    GvExMeasOM.setdefault(GL[index],[]).append(fid.readline())
    GvExMeasOM[GL[index]][0]=GvExMeasOM[GL[index]][0].split()
    GvExMeasOM[GL[index]][0]=map(int,GvExMeasOM[GL[index]][0])
    
    #mean_IA position_x position_y position_z pos_chisq
    PosDict.setdefault(GL[index],[]).append(fid.readline())
    PosDict[GL[index]][0]=PosDict[GL[index]][0].split()
    PosDict[GL[index]][0]=map(float,PosDict[GL[index]][0])
    # Orientation matrices
    for i in range(3):
        UDict.setdefault(GL[index],[]).append(fid.readline())
        UDict[GL[index]][i]=UDict[GL[index]][i].split()
        UDict[GL[index]][i]=map(float,UDict[GL[index]][i])
    UDict[GL[index]]=np.asarray(UDict[GL[index]]).reshape(3,3)
    # Skip next line.....
    with suppress_stdout():
        print fid.readline()

    for i in range(3):
        UBDict.setdefault(GL[index],[]).append(fid.readline())
        UBDict[GL[index]][i]=UBDict[GL[index]][i].split()
        UBDict[GL[index]][i]=map(float,UBDict[GL[index]][i])       
    UBDict[GL[index]]=np.asarray(UBDict[GL[index]]).reshape(3,3)   
    
    with suppress_stdout():
        print fid.readline()
        
    # Rodriguez Vectors    
    DictRdz.setdefault(GL[index],[]).append(fid.readline())
    DictRdz[GL[index]][0]=DictRdz[GL[index]][0].split()
    DictRdz[GL[index]][0]=map(float,DictRdz[GL[index]][0])
    
    # Skip next line ....
    with suppress_stdout():
        print fid.readline()
    # Extract Euler Angles for each grain   
    EulerDict.setdefault(GL[index],[]).append(fid.readline())
    EulerDict[GL[index]][0]=EulerDict[GL[index]][0].split()
    EulerDict[GL[index]][0]=map(float,EulerDict[GL[index]][0])
    
    # Skip next line ....
    with suppress_stdout():
        print fid.readline()
    
    qDict.setdefault(GL[index],[]).append(fid.readline())
    qDict[GL[index]][0]=qDict[GL[index]][0].split()
    qDict[GL[index]][0]=map(float,qDict[GL[index]][0])

    # Skip next line ....
    with suppress_stdout():
        print fid.readline()  
    
  #  gvector_id peak_id  h k l  h_pred k_pred l_pred  dh dk dl  tth_meas tth_pred dtth  omega_meas omega_pred domega  eta_meas  eta_pred deta  IA
    for i in range(GvExMeasOM[GL[index]][0][1]):
        GvecTable.setdefault(GL[index],[]).append(fid.readline())
        GvecTable[GL[index]][i]=GvecTable[GL[index]][i].split()
        GvecTable[GL[index]][i]=map(float,GvecTable[GL[index]][i])   
    
    GvecTable[GL[index]]=np.asarray(GvecTable[GL[index]]).reshape(GvExMeasOM[GL[index]][0][1],22)  

     # Skip next line ....
    with suppress_stdout():
        print fid.readline()

        
  fid.close()    
  return GvExMeasOM,PosDict,UDict,UBDict,DictRdz,EulerDict,GvecTable

    
def main(flog):
  return Parser(flog)
    
if __name__=="__main__":
  main(flog)

   




      
        



            

    