Skip to content

Commit

Permalink
Add ts-generation for links [ANT-1084] (#1986)
Browse files Browse the repository at this point in the history
Co-authored-by: Florian Omnès <[email protected]>
Co-authored-by: Florian OMNES <[email protected]>
Co-authored-by: guilpier-code <[email protected]>
  • Loading branch information
4 people authored Jun 21, 2024
1 parent 7dbb39c commit 9e6cdcc
Show file tree
Hide file tree
Showing 18 changed files with 362 additions and 12 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ jobs:
os: ${{ env.os }}
variant: "parallel"

- name: Run tests for time series generator tool
if: ${{ env.RUN_SIMPLE_TESTS == 'true' }}
uses: ./.github/workflows/run-tests
with:
simtest-tag: ${{steps.simtest-version.outputs.prop}}
batch-name: ts-generator
os: ${{ env.os }}
variant: "tsgenerator"

- name: Run medium-tests
if: ${{ env.RUN_EXTENDED_TESTS == 'true' }}
uses: ./.github/workflows/run-tests
Expand Down
11 changes: 10 additions & 1 deletion .github/workflows/windows-vcpkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,15 @@ jobs:
os: ${{ env.test-platform }}
variant: "parallel"

- name: Run tests for time series generator tool
if: ${{ env.RUN_SIMPLE_TESTS == 'true' }}
uses: ./.github/workflows/run-tests
with:
simtest-tag: ${{steps.simtest-version.outputs.prop}}
batch-name: ts-generator
os: ${{ env.test-platform }}
variant: "tsgenerator"

- name: Run medium-tests
if: ${{ env.RUN_EXTENDED_TESTS == 'true' }}
uses: ./.github/workflows/run-tests
Expand Down Expand Up @@ -304,7 +313,7 @@ jobs:
run: |
cd _build
cpack -G ZIP
- name: Installer upload
uses: actions/upload-artifact@v4
with:
Expand Down
20 changes: 20 additions & 0 deletions docs/user-guide/04-migration-guides.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Migration guides
This is a list of all recent changes that came with new Antares Simulator features. The main goal of this document is to lower the costs of changing existing interfaces, both GUI and scripts.

## v9.2.0
### (TS-generator only) TS generation for link capacities
In files input/links/<link1>/properties.ini, add the following properties
- tsgen_direct_XXX,
- tsgen_indirect_XXX
with XXX in
- unitcount (unsigned int, default 1)
- nominalcapacity (float)
- law.planned (string "uniform"/"geometric")
- law.forced (same)
- volatility.planned (double in [0,1])
- volatility.forced (same)

- "prepro" timeseries => input/links/<link 1>/prepro/<link 2>_{direct, indirect}.txt, 365x6 values, respectively "forced outage duration", "planned outage duration", "forced outage rate", "planned outage rate", "minimum of groups in maintenance", "maximum of groups in maintenance".
- "modulation" timeseries => input/links/<link 1>/prepro/<link 2>_mod_{direct, indirect}.txt, 8760x1 values each in [0, 1]
- number of TS to generate => generaldata.ini/General/nbtimeserieslinks (unsigned int, default value 1)



## v9.1.0
### Input
#### Hydro Maximum Generation/Pumping Power
Expand Down
106 changes: 104 additions & 2 deletions src/libs/antares/study/area/links.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@

#include "antares/study/area/links.h"

#include <filesystem>
#include <limits>

#include <boost/algorithm/string/case_conv.hpp>

#include <yuni/yuni.h>

#include <antares/exception/LoadingError.hpp>
Expand Down Expand Up @@ -134,6 +137,58 @@ bool AreaLink::linkLoadTimeSeries_for_version_820_and_later(const AnyString& fol
return success;
}

// This function is "lazy", it only loads files if they exist
// and set a `valid` flag
bool AreaLink::loadTSGenTimeSeries(const fs::path& folder)
{
const std::string idprepro = std::string(from->id) + "/" + std::string(with->id);
tsGeneration.prepro =
std::make_unique<Data::PreproAvailability>(idprepro, tsGeneration.unitCount);

bool anyFileWasLoaded = false;

// file name without suffix, .txt for general infos and mod_direct/indirect.txt
fs::path preproFile = folder / "prepro" / with->id.c_str();

// Prepro
fs::path filepath = preproFile;
filepath += ".txt";
if (fs::exists(filepath))
{
anyFileWasLoaded = true;
tsGeneration.valid = tsGeneration.prepro->data.loadFromCSVFile(
filepath.string(),
Antares::Data::PreproAvailability::preproAvailabilityMax,
DAYS_PER_YEAR)
&& tsGeneration.prepro->validate();
}

// Modulation
filepath = preproFile;
filepath += "_mod_direct.txt";
if (fs::exists(filepath))
{
anyFileWasLoaded = true;
tsGeneration.valid &= tsGeneration.modulationCapacityDirect
.loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR);
}

filepath = preproFile;
filepath += "_mod_indirect.txt";
if (fs::exists(filepath))
{
anyFileWasLoaded = true;
tsGeneration.valid &= tsGeneration.modulationCapacityIndirect
.loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR);
}

if (anyFileWasLoaded)
{
return tsGeneration.valid;
}
return true;
}

bool AreaLink::isLinkPhysical() const
{
// All link types are physical, except arVirt
Expand Down Expand Up @@ -448,13 +503,55 @@ bool handleKey(Data::AreaLink& link, const String& key, const String& value)
link.filterYearByYear = stringIntoDatePrecision(value);
return true;
}
return false;
}

bool handleTSGenKey(Data::LinkTsGeneration& out,
const std::string& key,
const String& value)
{

if (key == "unitcount")
{
return value.to<uint>(out.unitCount);
}

if (key == "nominalcapacity")
{
return value.to<double>(out.nominalCapacity);
}

if (key == "law.planned")
{
return value.to(out.plannedLaw);
}

if (key == "law.forced")
{
return value.to(out.forcedLaw);
}

if (key == "volatility.planned")
{
return value.to(out.plannedVolatility);
}

if (key == "volatility.forced")
{
return value.to(out.forcedVolatility);
}

if (key == "force-no-generation")
{
return value.to<bool>(out.forceNoGeneration);
}

return false;
}

bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const String& value)
{
return handleKey(link, key, value);
return handleKey(link, key, value) || handleTSGenKey(link.tsGeneration, key, value);
}

[[noreturn]] void logLinkDataCheckError(const AreaLink& link, const String& msg, int hour)
Expand All @@ -475,7 +572,7 @@ bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const
}
} // anonymous namespace

bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::path& folder)
bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::path& folder, bool loadTSGen)
{
// Assert
assert(area);
Expand Down Expand Up @@ -601,6 +698,11 @@ bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::pa
}
}

if (loadTSGen)
{
ret = link.loadTSGenTimeSeries(folder) && ret;
}

// From the solver only
if (study.usedByTheSolver)
{
Expand Down
2 changes: 1 addition & 1 deletion src/libs/antares/study/area/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study,
// Links
{
fs::path folder = fs::path(study.folderInput.c_str()) / "links" / area.id.c_str();
ret = AreaLinksLoadFromFolder(study, list, &area, folder) && ret;
ret = AreaLinksLoadFromFolder(study, list, &area, folder, options.linksLoadTSGen) && ret;
}

// UI
Expand Down
2 changes: 1 addition & 1 deletion src/libs/antares/study/cleaner/cleaner-v20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ bool listOfFilesAnDirectoriesToKeep(StudyCleaningInfos* infos)
logs.verbosityLevel = Logs::Verbosity::Warning::level;
// load all links
buffer.clear() << infos->folder << "/input/links/" << area->id;
if (not AreaLinksLoadFromFolder(*study, arealist, area, buffer.c_str()))
if (not AreaLinksLoadFromFolder(*study, arealist, area, buffer.c_str(), false))
{
delete arealist;
delete study;
Expand Down
4 changes: 4 additions & 0 deletions src/libs/antares/study/fwd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ const char* SeedToCString(SeedIndex seed)
return "Noise on virtual Hydro costs";
case seedHydroManagement:
return "Initial reservoir levels";
case seedTsGenLinks:
return "Links time-series generation";
case seedMax:
return "";
}
Expand Down Expand Up @@ -85,6 +87,8 @@ const char* SeedToID(SeedIndex seed)
return "seed-hydro-costs";
case seedHydroManagement:
return "seed-initial-reservoir-levels";
case seedTsGenLinks:
return "seed-tsgen-links";
case seedMax:
return "";
}
Expand Down
3 changes: 2 additions & 1 deletion src/libs/antares/study/include/antares/study/area/area.h
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,8 @@ AreaLink* AreaAddLinkBetweenAreas(Area* area, Area* with, bool warning = true);
bool AreaLinksLoadFromFolder(Study& s,
AreaList* l,
Area* area,
const std::filesystem::path& folder);
const std::filesystem::path& folder,
bool loadTSGen);

/*!
** \brief Save interconnections of a given area into a folder (`input/areas/[area]/ntc`)
Expand Down
5 changes: 5 additions & 0 deletions src/libs/antares/study/include/antares/study/area/links.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class AreaLink final: public Yuni::NonCopyable<AreaLink>

bool loadTimeSeries(const StudyVersion& version, const AnyString& folder);

bool loadTSGenTimeSeries(const std::filesystem::path& folder);

void storeTimeseriesNumbers(Solver::IResultWriter& writer) const;

//! \name Area
Expand Down Expand Up @@ -206,6 +208,9 @@ class AreaLink final: public Yuni::NonCopyable<AreaLink>
int linkWidth;

friend struct CompareLinkName;

LinkTsGeneration tsGeneration;

}; // class AreaLink

struct CompareLinkName final
Expand Down
2 changes: 2 additions & 0 deletions src/libs/antares/study/include/antares/study/fwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ enum SeedIndex
seedHydroCosts,
//! Seed - Hydro management
seedHydroManagement,
//! The seed for links
seedTsGenLinks,
//! The number of seeds
seedMax,
};
Expand Down
4 changes: 4 additions & 0 deletions src/libs/antares/study/include/antares/study/load-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ class StudyLoadOptions
bool loadOnlyNeeded;
//! Force the year-by-year flag
bool forceYearByYear;

//! Load data associated to link TS generation
bool linksLoadTSGen = false;

//! Force the derated mode
bool forceDerated;

Expand Down
2 changes: 2 additions & 0 deletions src/libs/antares/study/include/antares/study/parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ class Parameters final
uint nbTimeSeriesThermal;
//! Nb of timeSeries : Solar
uint nbTimeSeriesSolar;
//! Nb of timeSeries : Links
uint nbLinkTStoGenerate = 1;
//@}

//! \name Time-series refresh
Expand Down
9 changes: 9 additions & 0 deletions src/libs/antares/study/parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,10 @@ static bool SGDIntLoadFamily_General(Parameters& d,
{
return value.to<uint>(d.nbTimeSeriesSolar);
}
if (key == "nbtimeserieslinks")
{
return value.to<uint>(d.nbLinkTStoGenerate);
}
// Interval values
if (key == "refreshintervalload")
{
Expand Down Expand Up @@ -1054,6 +1058,10 @@ static bool SGDIntLoadFamily_SeedsMersenneTwister(Parameters& d,
{
return value.to<uint>(d.seed[seedTsGenSolar]);
}
if (key == "seed_links")
{
return value.to<uint>(d.seed[seedTsGenLinks]);
}
if (key == "seed_timeseriesnumbers")
{
return value.to<uint>(d.seed[seedTimeseriesNumbers]);
Expand Down Expand Up @@ -1783,6 +1791,7 @@ void Parameters::saveToINI(IniFile& ini) const
section->add("nbTimeSeriesWind", nbTimeSeriesWind);
section->add("nbTimeSeriesThermal", nbTimeSeriesThermal);
section->add("nbTimeSeriesSolar", nbTimeSeriesSolar);
section->add("nbtimeserieslinks", nbLinkTStoGenerate);

// Refresh
ParametersSaveTimeSeries(section, "refreshTimeSeries", timeSeriesToRefresh);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,7 @@ static inline void logPerformedYearsInAset(setOfParallelYears& set)
<< " perfomed)";

std::string performedYearsToLog = "";

std::ranges::for_each(set.yearsIndices,
[&set, &performedYearsToLog](const uint& y)
{
Expand Down
Loading

0 comments on commit 9e6cdcc

Please sign in to comment.