Управление конвейером
Автор
"""___________________________________________________________________________________
`get_sim_results(источник::String, example_path::String)`
Выполняет модель или возвращает simout ил jld2 файла
`источник` - любая строка, содержащая ".engee" или ".jld2"
`example_path` - директория с файлом-источником
___________________________________________________________________________________"""
function get_sim_results(источник::String, example_path::String)
if occursin(".engee", источник)
name = filter(x->occursin(".engee", x), readdir(example_path))[1]
try
engee.close(split(name, '.')[1], force=true) # закрытие модели
catch err # в случае, если нет модели, которую нужно закрыть и engee.close() не выполняется, то будет выполнена её загрузка после catch
m = engee.load(joinpath(example_path, name)) # загрузка модели
end;
try
engee.run(m) # запуск модели
catch err # в случае, если модель не загружена и engee.run() не выполняется, то будут выполнены две нижние строки после catch
m = engee.load(joinpath(example_path, name)) # загрузка модели
engee.run(m) # запуск модели
end
else
name = filter(x->occursin(".jld2", x), readdir(example_path))[1]
return load(name)["simout"]
end
end
"""___________________________________________________________________________________
`get_sim_data(simout::SimulationResult, signal::String, pos::Int64, data::String)::Vector{Float64}`
Извлекает заданный параметр из `simout`
Параметры
- `signal`: имя записываемого сигнала
- `pos`: его местонахождение в векторе
- `data`: тип возвращаемых данных time или value
Возвращает вектор значений из `simout`
___________________________________________________________________________________"""
function get_sim_data(simout::SimulationResult, signal::String, pos::Int64, data::String)::Vector{Float64}
sim_data::Vector{Float64}=[]
if data=="value"
for i in collect(simout[signal]).value
push!(sim_data, i[pos])
end
return sim_data
elseif data=="time"
sim_data = collect(simout[signal]).time
return sim_data
else
println("Допустимые значения параметра data: value, time")
end
end
"""___________________________________________________________________________________
`thin_vector(data::Vector{T}, step::Int, tolerance::Float64)::Vector{T} where T<:Number`
Прореживает вектор чисел на основе заданного шага и степени отклонения.
Правило прореживания:
Для каждой группы из `step` последовательных элементов:
1. Первый элемент группы становится "якорем" (`anchor`).
2. Для каждого последующего элемента `x` в группе вычисляется относительная разница:
`rel_diff = abs(x - anchor) / abs(anchor)` (если anchor != 0)
`rel_diff = abs(x - anchor)` (если anchor == 0)
3. Если `rel_diff <= tolerance`, элемент `x` удаляется.
4. Если `rel_diff > tolerance`, элемент `x` сохраняется.
Аргументы:
- `data::Vector{T}`: Исходный вектор чисел.
- `step::Int`: Размер шага (размер группы).
- `tolerance::Float64`: Степень отклонения (от 0 до 1). Элементы с относительной разницей <= tolerance удаляются.
Возвращает:
- `Vector{T}`: Новый вектор с удаленными элементами.
___________________________________________________________________________________"""
function thin_vector(data::Vector{T}, step::Int, tolerance::Float64)::Vector{T} where T<:Number
# Проверка входных данных
if step <= 0
throw(ArgumentError("Шаг (step) должен быть положительным целым числом. Получено: $step"))
end
if !(0.0 <= tolerance <= 1.0)
throw(ArgumentError("Степень отклонения (tolerance) должна быть в диапазоне [0, 1]. Получено: $tolerance"))
end
if isempty(data)
return T[] # Возвращаем пустой вектор того же типа
end
result = T[] # Инициализируем пустой вектор результата
n = length(data)
# Итерируемся по группам с шагом `step`
for start_idx in 1:step:n
# Определяем конечный индекс группы
end_idx = min(start_idx + step - 1, n)
# Проверяем, есть ли элементы в группе
if start_idx > n
break # Если начальный индекс вышел за пределы вектора, завершаем
end
# Якорь - это первый элемент текущей группы
anchor = data[start_idx]
# Добавляем якорь в результат
push!(result, anchor)
# Проверяем остальные элементы в группе
for i in (start_idx + 1):end_idx
x = data[i]
rel_diff = 0.0
# Вычисляем относительную разницу
if anchor != zero(T) # Проверка на ноль с учётом типа T
rel_diff = abs(x - anchor) / abs(anchor)
else
# Если якорь 0, используем абсолютную разницу как относительную
rel_diff = abs(x)
end
# Если относительная разница больше допустимой, сохраняем элемент
if rel_diff > tolerance
push!(result, x)
end
end
end
return result
end
"""
`thin(vector::Vector, step::Int64)::Vector`
Функция прореживания вектора `vector` с заданным шагом `step`
Возвращает новый вектор
"""
function thin(vector::Vector, step::Int64)
return vector[1:step:end]
end
"""___________________________________________________________________________________
`TxtToVec(Path::String)::Vector{Int64}`
Функция
- получает файл путь к файлу .txt, который содержит строки чисел
- возвращает вектор из этих чисел
___________________________________________________________________________________"""
function TxtToVec(path::String)::Vector{Int64}
try
return open(path, "r") do f
[parse(Int64, strip(line)) for line in eachline(f) if !isempty(strip(line))]
end
catch e
@error "Ошибка при чтении файла или преобразовании чисел" exception=(e, catch_backtrace())
rethrow()
end
end