classdef ML_inpt_att2
    %UNTITLED Summary of this class goes here
    %   Detailed explanation goes here
    
    
    %HISTORY:
    %2016- working version of code finished (dunno excacter date)
    %Feb 2017: Added 
    %July 2017: Made mac friendly version (Nowj ust better code in general
    %           too). No more reliance on '\' for path delimiting
    
    properties
        energies;   %nx1(row) vector containing energies of MOs (in eV)
        intensities; %nxm matrix containing contributions to the MO with energy given by energies(n,1). DOES NOT INCLUDE THE TDOS (you have to sum the row to get this)
        fragment_labels; %list of fragment labels (1 label per position) used to extract x_sections later (e.g S3D N2D) 
        m_factor; %factor to multiply a fragments contribution by (in case calc. system stoichiometry doesnt match experimental)
        frag_tdos;  %Sum of the intensities row. essentially the pDoS for this fragment. WARNING: OBVIOUSLY NOT UPDATED AUTOMATICALLY IF YOU UPDATE DIFF FIELD
        numb_MOs;   %Simply number of rows in energies/intensities. But i like to be explicit
        %Properties below are all related to creating a new MLinpt.txt file easily(write_new_file_method)
        first_line;	%first_line and second_line are literally the 1st and 2nd lines of input file. Purpoes of having them here is that a new input file can easily be created from this object.
        second_line;
        base_fname;	%As input file is *_MLinpt.txt format,base_fname is the * part of that (e.g cheese_MLinpt.txt, base_fname = 'cheese')
        base_path;	%Path to foldere containng the original *_MLinpt.txt file
        
    end
    methods
            %filename = obbviously the full path of file to import
            %max_e = cutoff for orbital BINDING energy (orbitals with higher B.E will be deleted)(OPTIONAL ARGUMENT)
            %min_e = cutoff for orbital BINDING energy (orbitals with lower B.E will be deleted)(OPTIONAL ARGUMENT)
            function obj = ML_inpt_att2(filename)
                %NOTE: CANT GIVE AN ERROR FOR 0 arguments, otherwise i cant
                %initialise an object array (gj matlab.....)
                %if nargin==0       
                %    error('Need at least a filepath argument for ML_inpt Class')
                %end
                if nargin>0
                if nargin==1
                    min_e = -10000000;
                    max_e = 100000000;
                end
        [obj.base_path , obj.base_fname] = fileparts(filename);
        obj.base_fname = strrep(obj.base_fname,'_MLinpt.txt','');
		%temp = strrep(strsplit(filename,'\'),'_MLinpt.txt',''); obj.base_fname=temp{end};	%would probably work(but might need two lines) 
		%obj.base_path = strjoin(temp(1:end-1),'\');
		inp_file = fileread(filename);
                inp_file = strsplit(inp_file,'\n');	%String list/cell array containing lines of input file
		obj.first_line = inp_file{1};
		obj.second_line = inp_file{2};
                obj.m_factor = str2num ( strrep(inp_file{1},'# M_FACTOR=','') );
                fragment_labels = strsplit(inp_file{2},',');
                fragment_labels = fragment_labels(3:end);	%All fragment labels,NOT TDOS and energies though
                obj.fragment_labels = fragment_labels;
                numb_cols = size(fragment_labels,2) + 1; %Columns in data matrix, 1 more than frag_labels as it includes energy
                data_array = zeros(size(inp_file,2)-3,numb_cols);
                
                %POSSIBLE ERROR:inp_file has empty column@end, hence the -1 in loop. May cause problems somehow.
                %Putting energies+intensities into 1 grid (data_array-not TDOS column tho)
                for cls_loopvar1=3:size(inp_file,2)-1
                    temp_list = strsplit(inp_file{cls_loopvar1},',');
                    counter=1;
                    for cls_loopvar2=1:size(temp_list,2)
                        if cls_loopvar2~=2		%Gets rid of the TDOS column
                            data_array(cls_loopvar1-2,counter) = str2num(temp_list{cls_loopvar2});
                            counter=counter+1;
                        end
                    end
                end
                
                %Converting energies to binding energies and removing energies
                %above/below threshold
                %POSSIBLE ERROR:code assumes highest value=1st entry (as it should be but..)
                data_array(:,1) = data_array(:,1)*-1;
                e_upper=1;	%index of highest energy MO we want
                e_lower=size(data_array,1);
                for cls_loopvar1=1:size(data_array,1)
                    if data_array(cls_loopvar1,1) > max_e
                        e_upper = cls_loopvar1 +1;
                    end
                    if data_array(size(data_array,1)-cls_loopvar1+1,1) < min_e
                        e_lower = size(data_array,1)-cls_loopvar1;
                    end
                end
                obj.energies = data_array(e_upper:e_lower,1);
                obj.intensities = data_array(e_upper:e_lower,2:end);
                obj.frag_tdos = NaN(size(obj.intensities,1),1);
                for cls_loopvar1=1:size(obj.intensities,1)
                   obj.frag_tdos(cls_loopvar1,1) = sum(obj.intensities(cls_loopvar1,:)); 
                end
                obj.numb_MOs = size(obj.energies,1);
                end
                
            end
    
            %Writes *MLinpt.txt file with current object attributes
            %(energies/intensities/base_fname/base_path/m_factor)
            %Modify object properties to modify output ldo
            function [] = write_file(obj)
                
                %Preparing the delimited data (energies/intensities)
                output_data = [obj.energies*-1 NaN(size(obj.energies,1),1) obj.intensities];
                for i =1:size(output_data,1)
                   output_data(i,2) =  sum(obj.intensities(i,:));
                end
                
                save_path = fullfile(obj.base_path,obj.base_fname);
                %Writing header
                output_filename = [save_path '_MLinpt.txt']; %Full path to output file
                fobject1 = fopen(output_filename,'w');
                fprintf(fobject1,['# M_FACTOR=' num2str(obj.m_factor) '\n']);
                fprintf(fobject1,['# Energy (eV),TDOS,' strjoin(obj.fragment_labels,',') '\n']);
                fclose(fobject1);
                %Writing data
                dlmwrite(output_filename,output_data,'-append','precision','%.6f');
                
            end
            
    
    end

    
    
    methods (Static)
        
        %Takes folder as an argument and returns object array contaning an
        %MLinpt object for each *MLinpt.txt file in folder
        %INput argument is obviously just full path to folder of interest
        function [MLinpt_obj_array] = create_MLinpt_obj_array_folder(folder)
%           file_list = dir([folder '\*MLinpt*.txt']); %nx1 structure containing all relevant file names
           file_list = dir(fullfile(folder,'*MLinpt.txt'));
           MLinpt_obj_array(size(file_list,1),1) = ML_inpt_att2;
           for i =1:size(MLinpt_obj_array,1)
               MLinpt_obj_array(i,1) = ML_inpt_att2(   fullfile(folder,file_list(i,1).name)    );
           end
           
           
        end
        
        
    end
    
    
    

end
