-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CGMES : Implement a pre-processor that completes the CGMES model with missing containers before starting the conversion #2463
CGMES : Implement a pre-processor that completes the CGMES model with missing containers before starting the conversion #2463
Conversation
… missing containers before starting the conversion Signed-off-by: Luma <zamarrenolm@aia.es>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some remarks to open a discussion
...nversion/src/main/java/com/powsybl/cgmes/conversion/DefineMissingContainersPreProcessor.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
…itten Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
When no folder is specified as parameter, the completion files are written in a temp directory created from the current |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if this pre-processor's place is in core at all.... The feature of CGMES pre-processors in itself is very nice and a good idea! But this one is, I think, about a use-case that is too specific to be in core. Maybe it can be in another repo? @annetill do you have any opinion?
cgmes/cgmes-completion/pom.xml
Outdated
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
|
||
Copyright (c) 2017, RTE (http://www.rte-france.com) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*copyright 2023
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
<logger name="com.powsybl.triplestore.TripleStore" level="error"/> | ||
<logger name="com.powsybl.cgmes.triplestore.CgmesModelTripleStore" level="error"/> | ||
<logger name="com.powsybl.cgmes.conversion.Conversion" level="error"/> | ||
<logger name="com.powsybl.cgmes.completion" level="info"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the log level info here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the unit tests, to have easy access to the relevant info about the run (location of the output file, list of missing voltage levels in the input) ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be modified by the dev for debug, but I think by default, it should be error
to limit logs during simple compilation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log level updated to error
@@ -28,6 +29,7 @@ | |||
/** | |||
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com> | |||
*/ | |||
// FIXME(Luma) rename to CgmesImportProcessorsTest (we will test both pre- and post- processors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can rename it now :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I forgot to do it. I have renamed the test class as CgmesImportPreAndPostProcessorsTest
* @author Luma Zamarreño <zamarrenolm at aia.es> | ||
*/ | ||
@AutoService(CgmesImportPreProcessor.class) | ||
public class DefineMissingContainersPreProcessor implements CgmesImportPreProcessor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe CreateMissingContainersPreProcessor
is more explicit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
To explain my viewpoint more in details, there are some processors we use in private repo because they are too specific to one company's use cases and I think this is the same here... Core is supposed to have standards processes. Even ENTSO-E processes are not in here. |
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
Generic scheme for pre-processors has been moved to #2513. Once it is merged in main, we will leave here only the specific code for completing CGMES model with missing containers using the pre-processor mechanism. |
Signed-off-by: Luma <zamarrenolm@aia.es>
Kudos, SonarCloud Quality Gate passed! |
@AutoService(CgmesImportPreProcessor.class) | ||
public class CreateMissingContainersPreProcessor implements CgmesImportPreProcessor { | ||
|
||
public static final String NAME = "CreateMissingContainers"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For homogenisation purposes, you can simply name it missingContainers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But for example the IIDM modification post-processor that replaces tie lines by lines starts also with a verb (replaceTieLinesByLines
). I prefer if we keep the action in the name. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is a difference between modifications (which state the action they do) and processors (which state the context, particularly for CGMES processors) but both are okay in my opinion but it should start with a low case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name now starts with lower case, createMissingContainers
.
I think of pre/post-processors as specialized tools carrying out specific tasks before/after CGMES import, so for me it is ok if their name starts with a verb.
...mpletion/src/main/java/com/powsybl/cgmes/completion/CreateMissingContainersPreProcessor.java
Outdated
Show resolved
Hide resolved
|
||
private static void buildZipFileWithFixes(Set<String> missingVoltageLevels, Path fixesFile, String basename) { | ||
Network network = NetworkFactory.findDefault().createNetwork("empty", "CGMES"); | ||
// TODO(Luma) should we ensure that context CIM version uses the same version of the input files ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate this TODO
for me? Not sure I understand
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have read CGMES files in a given version.
We should export CGMES files in the same version.
When the network is created applying conversion from CGMES files, the version of input data is stored in the extension CimCharacteristics
, and when an export context is created from a Network
, the version to use in the export is the same one that was read, unless explicitly changed.
Here we are creating an export context with an empty Network
that will not carry information about specific CIM version to use, so the default value will be used (CIM16).
I will set the CIM version in the context explicitly, based on the version of the input files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh okay, I think you directly retrieve it from the model:
int cim = 16;
if (model instanceof CgmesModelTriplestore) {
cim = ((CgmesModelTriplestore) model).getCimVersion();
} else {
// warning
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is what is done in the method prepareEmptyNetworkForExport
. The CIM version read from the input files is set in the CimCharacteristics
extension of the "empty" IIDM Network that is used to generate the CGMES files that will define the missing containers.
...mpletion/src/main/java/com/powsybl/cgmes/completion/CreateMissingContainersPreProcessor.java
Outdated
Show resolved
Hide resolved
...mpletion/src/main/java/com/powsybl/cgmes/completion/CreateMissingContainersPreProcessor.java
Outdated
Show resolved
Hide resolved
LOG.warn("Missing fixes folder parameter {}, attempt to create a temp directory in user working directory.", FIXES_FOLDER_NAME_PARAMETER.getName()); | ||
Path current = Path.of(System.getProperty("user.dir")); | ||
String prefix = "cgmes-fixes-for-missing-containers"; | ||
boolean debug = false; | ||
try (WorkingDirectory workingDirectory = new WorkingDirectory(current, prefix, debug)) { | ||
buildFixesOnFolder(cgmes, basename, workingDirectory.toPath()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I agree with this.... Not really a good thing to "silently" write. For me, it should like usual export, if not defined, it should either fail or at the very least, use directory of PlatformConfig
but I think we wanted to limit the use of that (@flo-dup you can correct me if I'm wrong)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When not specified through the corresponding parameter the pre-processor does not run. An error is logged.
For the tests I have used a Jimfs filesystem, through the test platform config and local computation manager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, after re-reading, I think you need to add a FileSystem
as parameter in the preprocessor (by default FileSystem.getDefault()
) and use that to create/delete files. It is cleaner and that would also allow to test it properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to solve the issue (and do proper testing) without the need of a explicit additional parameter for FileSystem
.
When we obtain the folder parameter from config:
- if it is an absolute path the default file system is used.
- If the path is relative, it is assumed relative to the platform config dir.
In the tests, we create a platform config that lives in the Jimfs file system, following the same schema applied in other unit tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I left a comment below, your solution is okay for me
<logger name="com.powsybl.triplestore.TripleStore" level="error"/> | ||
<logger name="com.powsybl.cgmes.triplestore.CgmesModelTripleStore" level="error"/> | ||
<logger name="com.powsybl.cgmes.conversion.Conversion" level="error"/> | ||
<logger name="com.powsybl.cgmes.completion" level="info"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be modified by the dev for debug, but I think by default, it should be error
to limit logs during simple compilation
// The only way to pass the output folder where we want the fixes to be written is to use a config file | ||
// Its contents should be: | ||
// | ||
// import-export-parameters-default-value: | ||
// iidm.import.cgmes.fixes-for-missing-containers-filename: "/user/working/area/fixes/..." | ||
// | ||
// For tests, it is not possible to put a reference to a Jimfs folder, | ||
// Even if we write the uri of the folder, and read it back as an uri, | ||
// the default file system is used to interpret it | ||
// | ||
// An alternative would be to write in the config a temp folder that we create here in the tests, | ||
// But that means writing in a resource file (the actual path of the temp folder), it is dirty. | ||
// | ||
// Instead, the CGMES completion processor creates itself a temp folder when no parameter is received. | ||
// We won't receive directly the file with the fixes, but we do not care. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the issue with writing a temporary file using Jimfs URIs, it is cleaner that writing temporarily in user.dir
in my opinion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not want to use Jimfs directly in the preprocessor: in the rest of PowSyBl core this library is only included in test code. It will add a new dependency in the framework.
The problem is that we can not setup a Jimfs folder inside the test code that is then used in the preprocessor: no way to put a reference in the config file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solved the issue passing a computation manager with a test platform config.
During the tests the temp files are written to a Jimfs filesystem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just seen this message, I'm keeping the previous one, not sure which solution is best, a suggestion @olperr1 ? Both are okay in my opinion
Signed-off-by: Luma <zamarrenolm@aia.es>
Signed-off-by: Luma <zamarrenolm@aia.es>
Removed the "silent" write if the output folder for fixes is not defined in the configuration. |
import java.util.zip.ZipOutputStream; | ||
|
||
/** | ||
* @author Luma Zamarreño <zamarrenolm at aia.es> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a (light) javadoc, just to explain what is done in this pre-processor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added a small javadoc
@AutoService(CgmesImportPreProcessor.class) | ||
public class CreateMissingContainersPreProcessor implements CgmesImportPreProcessor { | ||
|
||
public static final String NAME = "CreateMissingContainers"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is a difference between modifications (which state the action they do) and processors (which state the context, particularly for CGMES processors) but both are okay in my opinion but it should start with a low case
|
||
private static void buildZipFileWithFixes(Set<String> missingVoltageLevels, Path fixesFile, String basename) { | ||
Network network = NetworkFactory.findDefault().createNetwork("empty", "CGMES"); | ||
// TODO(Luma) should we ensure that context CIM version uses the same version of the input files ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh okay, I think you directly retrieve it from the model:
int cim = 16;
if (model instanceof CgmesModelTriplestore) {
cim = ((CgmesModelTriplestore) model).getCimVersion();
} else {
// warning
}
LOG.warn("Missing fixes folder parameter {}, attempt to create a temp directory in user working directory.", FIXES_FOLDER_NAME_PARAMETER.getName()); | ||
Path current = Path.of(System.getProperty("user.dir")); | ||
String prefix = "cgmes-fixes-for-missing-containers"; | ||
boolean debug = false; | ||
try (WorkingDirectory workingDirectory = new WorkingDirectory(current, prefix, debug)) { | ||
buildFixesOnFolder(cgmes, basename, workingDirectory.toPath()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, after re-reading, I think you need to add a FileSystem
as parameter in the preprocessor (by default FileSystem.getDefault()
) and use that to create/delete files. It is cleaner and that would also allow to test it properly.
// The only way to pass the output folder where we want the fixes to be written is to use a config file | ||
// Its contents should be: | ||
// | ||
// import-export-parameters-default-value: | ||
// iidm.import.cgmes.fixes-for-missing-containers-filename: "/user/working/area/fixes/..." | ||
// | ||
// For tests, it is not possible to put a reference to a Jimfs folder, | ||
// Even if we write the uri of the folder, and read it back as an uri, | ||
// the default file system is used to interpret it | ||
// | ||
// An alternative would be to write in the config a temp folder that we create here in the tests, | ||
// But that means writing in a resource file (the actual path of the temp folder), it is dirty. | ||
// | ||
// Instead, the CGMES completion processor creates itself a temp folder when no parameter is received. | ||
// We won't receive directly the file with the fixes, but we do not care. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just seen this message, I'm keeping the previous one, not sure which solution is best, a suggestion @olperr1 ? Both are okay in my opinion
Signed-off-by: Luma <zamarrenolm@aia.es>
Kudos, SonarCloud Quality Gate passed! |
Please check if the PR fulfills these requirements (please use
'[x]'
to check the checkboxes, or submit the PR and then click the checkboxes)Does this PR already have an issue describing the problem ? If so, link to this issue using
'#XXX'
and skip the rest#2458
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Feature
What is the current behavior? (You can also link to an open issue here)
CGMES import fails if containers (voltage levels) are referred but not defined in the set of input XML files.
What is the new behavior (if this is a feature change)?
A CGMES pre-processor scheme is proposed, following a similar approach to current post-processors.
Here we want to add plugins that intervene in the CGMES model AFTER the given CGMES data has been read but BEFORE the conversion is started.
This provides a point where we can configure a potentially time consuming process. It will be called only if the user activates it.
We inspect the initial CGMES model looking for missing data and try to complete it before the conversion starts.
Other information:
The implementation will build a new XML file that will contain the missing definitions.
After reading it to add its contents to the CGMES model in memory, we have to invalidate all previous caches.