#!/usr/bin/python
# -*- coding: utf-8 -*-
# Alpaga
# AnaLyse en PolArisation de la Generation de second hArmonique
import numpy as np
import os
import pickle
from scipy.optimize import curve_fit
import matplotlib
import matplotlib.pyplot as plt
############################################################################################
################################# File management #########################################
############################################################################################
[docs]
def standard_file_name(prefixe, angle=False, iteration=False, extension='.dat'):
'''
Define how to build the file name of an acquisition.
You may define your own function if your file does not follow the same structure.
However, we strongly recommend using the same input/output format as described below:
Parameters
----------
prefixe : str
The prefix of the file name.
angle : str or bool
[Optional] If not a bool, appends this 'angle' value to the file name.
iteration : str or bool
[Optional] If not a bool, appends this 'iteration' value to the file name.
extension : str
[Optional] The extension of the spectra file. Default is '.dat'.
Returns
-------
name : str
The generated file name.
Example
-------
For this standard function, if the input is:
prefixe = 'polarV'
angle = '42.0'
iteration = '4'
extension = '.dat'
The output will be: 'polarV_42.0_4.dat'
'''
if isinstance(angle, bool):
if isinstance(iteration, bool):
name = prefixe + extension
else:
name = prefixe + '_' + iteration + extension
else:
if isinstance(iteration, bool):
name = prefixe + '_' + angle + extension
else:
name = prefixe + '_' + angle + '_' + iteration + extension
return(name)
############################################################################################
def third_floor_file_name_builder(prefixe, angle=False, iteration=False, extension='.dat'):
'''
The function used to build the name of the file generated by the 3rd floor room.
'''
if isinstance(angle, bool): # case where no angle is given
if isinstance(iteration, bool): # case where no iteration is given
name = prefixe + extension
else: # case where an iteration is given
name = prefixe + '_acq' + iteration + extension
else: # case where an angle is given
if isinstance(iteration, bool): # case where no iteration is given
name = prefixe + '_' + angle + extension
else: # case where an iteration is given
name = prefixe + '_' + angle + '_acq' + iteration + extension
return(name)
############################################################################################
def transform_name_file(name_t, extension, type_file='single'):
"""
Internal function of Alpaga.
Parameters
----------
directory : str
The directory where the data is stored.
extension : str
[Optional] The extension of the spectra file. Default is '.dat'.
Returns
-------
prefix_file : str
For a given input name (*name_t*), this function splits the name into parts
to match one of the two possible templates depending on the argument *type_file*.
The extension of the file must match the input *extension*.
If *type_file* = 'single', the template is:
prefix + '_' + iter + extension
In this case, the function returns: prefix, iter, extension.
If *type_file* = 'angle', the template is:
prefix + '_' + angle + '_' + iter + extension
In this case, the function returns: prefix, angle, iter, extension.
"""
if type_file=='single':
if name_t[-len(extension):] != extension:
output = False
else:
trotter = 0
prefix_file = ''
number_iter = ''
t = -len(extension)-1
while trotter < 1: # this loop goes from the end of the file name to the begining since the important value for the code, angle and iter, are located at the end.
if name_t[t] == '_':
trotter += 1
elif trotter == 0:
number_iter += name_t[t]
else:
raise Exception('WARNING: problem code!!! The file name ' + name_t + ' is not standard! It should be: prefix_iter.dat')
t = t - 1
prefix_file = name_t[0:t+1]
number_iter = int(number_iter[::-1]) # the iter value are created in the opposite direction. The real angle value is the opposite
output = [prefix_file, number_iter]
elif type_file=='angle':
if name_t[-len(extension):] != extension:
output = False
else:
trotter = 0
prefix_file = ''
angle_t=''
number_iter = ''
t = -len(extension)-1
while trotter < 2: # this loop goes from the end of the file name to the begining since the important value for the code, angle and iter, are located at the end.
if name_t[t] == '_':
trotter += 1
elif trotter == 0:
number_iter += name_t[t]
elif trotter == 1:
angle_t += name_t[t]
else:
raise Exception('WARNING: problem code!!! The file name ' + name_t + ' is not standard! It should be: prefix_angle_iter.dat')
t = t - 1
prefix_file = name_t[0:t+1]
# angle_t = float(angle_t[::-1]) # the angle are created in the opposite direction. The real angle value is the opposite
angle_t = angle_t[::-1] # the angle are created in the opposite direction. The real angle value is the opposite
number_iter = int(number_iter[::-1]) # the iter value are created in the opposite direction. The real angle value is the opposite
output = [prefix_file, angle_t, number_iter]
else:
raise Exception('WARNING: type_file can only be "single" or "angle".')
return(output)
############################################################################################
[docs]
def find_file_iter_from_dir(directory, extension='.dat'):
"""
Return the prefix (*prefix_file*), the number of iterations (*N_iter*),
and the extension (*extension*) of a single acquisition located in the directory *directory*.
The expected file naming convention is:
directory + prefix + '_' + i + extension
where *i* ranges from 1 to *N_iter*.
Parameters
----------
directory : str
The directory where the data is stored.
extension : str
[Optional] The extension of the spectra file. Default is '.dat'.
Returns
-------
prefix_file : str
The prefix shared by all the spectra iterations.
N_iter : int
The number of iterations found for this prefix. Alpaga checks that
all iterations are present to avoid 'File not found' errors later on.
extension : str
The extension of the detected spectra file. Same value as the input.
Examples
--------
Suppose that in the directory ``/home/lama/Datas/Water_acquisition/Test_120sec``
there are the spectra files: ``water_1.dat, water_2.dat, water_3.dat``.
The prefix of these files is ``water``, the total number of iterations is
*N_iter* = 3, and the extension is ``.dat``.
To automatically extract this information, use: ::
directory = '/home/lama/Datas/Water_acquisition/Test_120sec'
prefix, N_iter, extension = alpaga.find_file_iter_from_dir(directory)
print('The prefix for all files is: "' + prefix + '" with '
+ str(N_iter) + ' iterations. The extension is: ' + extension)
"""
print('I will look at file with the extension ' + extension + ' in the directory ' + directory + ' for single acquisition. The type of the files should be: prefix_iter.extension')
all_file = os.listdir(directory)
L_files_iter= []
prefix_file_old = False
for KKK in range(0, len(all_file), 1):
name_t = all_file[KKK]
output = transform_name_file(name_t, extension, type_file='single')
if output: # False would mean that the file tested is not valid, and thus skiped. For instance bad format file.
prefix_file = output[0]
number_iter = output[1]
if not prefix_file_old:
prefix_file_old = prefix_file
else:
if prefix_file_old != prefix_file:
raise Exception('There are other file with the same extension but not the same prefix name. Please move these file, or do not use this module to creat the list! If you are looking for angle depend value, use the find_angle_iter_from_dir function.')
L_files_iter.append(number_iter)
N_iter = len(L_files_iter)
if N_iter == 0:
raise Exception('WARNING: I have not found any file with the good name type in this directory. Please check!')
# check the number of iter:
L_files_iter = sorted(L_files_iter)
if len(L_files_iter) != L_files_iter[-1]:
raise Exception('WARNING: There is not enough iter for this file. Please check that there are all the iter.')
N_iter = len(L_files_iter)
return(prefix_file, N_iter, extension)
############################################################################################
[docs]
def find_angle_iter_from_dir(directory, extension='.dat'):
"""
Return the prefix (*prefix_file*), the list of angles (*L_files_angles*),
the number of iterations (*N_iter*), and the extension (*extension*) of an acquisition
located in the directory *directory*.
The expected file naming convention is:
directory + prefix + '_' + k + '_' + i + extension
where *k* iterates over all values in *L_files_angles* (angles, possibly floats —
avoid excessively long decimal values), and *i* ranges from 1 to *N_iter*.
Parameters
----------
directory : str
The directory where the data is stored.
extension : str
[Optional] The extension of the spectra file. Default is '.dat'.
Returns
-------
prefix_file : str
The prefix shared by all spectra iterations.
L_files_angles : list of str
The list of detected angles. Returned as a list of strings
(to avoid issues with filenames such as '4.10').
N_iter : int
The number of iterations found for this prefix. Alpaga checks that all iterations
are present for all angles to avoid 'File not found' errors later on.
extension : str
The extension of the detected spectra file. Same as the input value.
Examples
--------
Suppose that in the directory ``/home/lama/Datas/Water_acquisition/Test_120sec``
the following spectra files are located:
``water_4.0_1.dat, water_4.0_2.dat, water_15.0_1.dat, water_15.0_2.dat``.
The prefix of these files is ``water``, the total number of iterations is *N_iter* = 2,
the list of angles is *L_files_angles* = ['4.0', '15.0'], and the extension is ``.dat``.
To automatically extract this information, use: ::
directory = '/home/lama/Datas/Water_acquisition/Test_120sec'
prefix, L_files_angles, N_iter, extension = alpaga.find_angle_iter_from_dir(directory)
print('The prefix for all files is: "' + prefix + '" with '
+ str(N_iter) + ' iterations. The angles found are '
+ str(L_files_angles) + '. The extension is: ' + extension)
"""
print('I will look at file with the extension ' + extension + ' in the directory ' + directory + 'for angle dependent values. The type of the files should be: prefix_angle_iter.extension')
all_file = os.listdir(directory)
L_files_angles = []
L_files_iter= []
prefix_file_old = False
for KKK in range(0, len(all_file), 1):
name_t = all_file[KKK]
output = transform_name_file(name_t, extension, type_file='angle')
if output: # False would mean that the file tested is not valid, and thus skiped. For instance bad format file.
prefix_file = output[0]
angle_t = output[1]
number_iter = output[2]
if isinstance(prefix_file_old, str) and prefix_file_old != prefix_file:
raise Exception('WARNING: the prefix to name the different file in the directory' + directory + ' are not the same! Please move the other spectra files!!!')
prefix_file_old = prefix_file
# print(prefix_file, angle_t, number_iter)
if L_files_angles: # if there are already other file in the list
is_found = False
angle_tt = float(angle_t)
for k in range(0, len(L_files_angles), 1):
angle_test = float(L_files_angles[k])
if np.abs(angle_test-angle_tt) < 0.01: # to avoid stupid float comparaison crashes
L_files_iter[k].append(number_iter)
is_found = True
if not is_found:
# print('not found:', angle_t)
L_files_angles.append(angle_t)
L_files_iter.append([number_iter])
else: # if the list is empty, add directly this file
L_files_angles.append(angle_t)
L_files_iter.append([number_iter])
N_angle = len(L_files_angles)
if N_angle == 0:
raise Exception('WARNING: I have not found any file with the good name type in this directory. Please check!')
# check the number of iter:
if len(L_files_iter) != N_angle:
raise Exception('WARNING: Bug, please check this line and above. Should be a code problem...')
to_check_iter = sorted(L_files_iter[0])
if len(to_check_iter) != to_check_iter[-1]:
raise Exception('WARNING: There is not enough iter for the angle: ' + str(L_files_angles[0]) + '. Please check that for every angle there is the same number of iter!')
for i in range(0, N_angle-1, 1):
temp = sorted(L_files_iter[i])
if len(temp) != len(to_check_iter):
raise Exception('WARNING: There is not enough iter for the angle: ' + str(L_files_angles[i]) + '. Please check that for every angle there is the same number of iter!')
for kkk in range(0, len(to_check_iter), 1):
if temp[kkk] != to_check_iter[kkk]:
raise Exception('WARNING: There is not enough iter for the angle: ' + str(L_files_angles[i]) + '. Please check that for every angle there is the same number of iter!')
# sort the angle values:
L_files_angles_float = [float(L_files_angles[k]) for k in range(0, len(L_files_angles))]
L_element = np.argsort(L_files_angles_float)
L_files_angles_sorted = []
for k in range(0, len(L_files_angles), 1):
L_files_angles_sorted.append(L_files_angles[L_element[k]])
L_files_angles = L_files_angles_sorted
N_iter = len(to_check_iter)
return(prefix_file, L_files_angles, N_iter, extension)