Skip to content
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

[CSA] Import ARA from time to implement only #1144

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@

package com.powsybl.openrao.data.cracio.csaprofiles;

import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider;
import com.powsybl.openrao.data.cracio.csaprofiles.craccreator.CsaProfileCracUtils;
import com.powsybl.openrao.data.cracio.csaprofiles.craccreator.NcPropertyBagsConverter;
import com.powsybl.openrao.data.cracio.csaprofiles.craccreator.constants.CsaProfileConstants;
import com.powsybl.openrao.data.cracio.csaprofiles.craccreator.constants.CsaProfileKeyword;
import com.powsybl.openrao.data.cracio.csaprofiles.craccreator.constants.HeaderType;
import com.powsybl.openrao.data.cracio.csaprofiles.craccreator.constants.OverridingObjectsFields;
import com.powsybl.openrao.data.cracio.csaprofiles.craccreator.Query;
import com.powsybl.openrao.data.cracio.csaprofiles.nc.*;
import com.powsybl.triplestore.api.PropertyBag;
import com.powsybl.triplestore.api.PropertyBags;
import com.powsybl.triplestore.api.QueryCatalog;
import com.powsybl.triplestore.api.TripleStore;

import java.lang.reflect.InvocationTargetException;
import java.time.OffsetDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author Jean-Pierre Arnould {@literal <jean-pierre.arnould at rte-france.com>}
Expand All @@ -34,12 +35,14 @@ public class CsaProfileCrac {

private final Map<String, Set<String>> keywordMap;
private Map<String, String> overridingData;
private Map<Class<? extends NCObject>, Set<? extends NCObject>> queriedNativeObjects;

public CsaProfileCrac(TripleStore tripleStoreCsaProfileCrac, Map<String, Set<String>> keywordMap) {
this.tripleStoreCsaProfileCrac = tripleStoreCsaProfileCrac;
this.queryCatalogCsaProfileCrac = new QueryCatalog(CsaProfileConstants.SPARQL_FILE_CSA_PROFILE);
this.keywordMap = keywordMap;
this.overridingData = new HashMap<>();
this.queriedNativeObjects = new HashMap<>();
}

public void clearContext(String context) {
Expand All @@ -64,138 +67,77 @@ private Set<String> getContextNamesToRequest(CsaProfileKeyword keyword) {

public Map<String, PropertyBags> getHeaders() {
Map<String, PropertyBags> returnMap = new HashMap<>();
tripleStoreCsaProfileCrac.contextNames().forEach(context -> returnMap.put(context, queryTripleStore(CsaProfileConstants.REQUEST_HEADER, Set.of(context))));
tripleStoreCsaProfileCrac.contextNames().forEach(context -> returnMap.put(context, queryTripleStore("header", Set.of(context))));
return returnMap;
}

public PropertyBags getPropertyBags(CsaProfileKeyword keyword, String... queries) {
Set<String> namesToRequest = getContextNamesToRequest(keyword);
public PropertyBags getPropertyBags(Query query) {
Set<String> namesToRequest = getContextNamesToRequest(query.getTargetProfilesKeyword());
if (namesToRequest.isEmpty()) {
return new PropertyBags();
}
return this.queryTripleStore(List.of(queries), namesToRequest);
return CsaProfileCracUtils.overrideQuery(this.queryTripleStore(List.of(query.getTitle()), namesToRequest), query, overridingData);
}

public PropertyBags getPropertyBags(CsaProfileKeyword keyword, OverridingObjectsFields withOverride, String... queries) {
return withOverride == null ? getPropertyBags(keyword, queries) : CsaProfileCracUtils.overrideData(getPropertyBags(keyword, queries), overridingData, withOverride);
}

public Set<Contingency> getContingencies() {
return new NcPropertyBagsConverter<>(Contingency::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.CONTINGENCY, OverridingObjectsFields.CONTINGENCY, CsaProfileConstants.REQUEST_ORDINARY_CONTINGENCY, CsaProfileConstants.REQUEST_EXCEPTIONAL_CONTINGENCY, CsaProfileConstants.REQUEST_OUT_OF_RANGE_CONTINGENCY));
}

public Set<ContingencyEquipment> getContingencyEquipments() {
return new NcPropertyBagsConverter<>(ContingencyEquipment::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.CONTINGENCY, CsaProfileConstants.REQUEST_CONTINGENCY_EQUIPMENT));
}

public Set<AssessedElement> getAssessedElements() {
return new NcPropertyBagsConverter<>(AssessedElement::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.ASSESSED_ELEMENT, OverridingObjectsFields.ASSESSED_ELEMENT, CsaProfileConstants.REQUEST_ASSESSED_ELEMENT));
}

public Set<AssessedElementWithContingency> getAssessedElementWithContingencies() {
return new NcPropertyBagsConverter<>(AssessedElementWithContingency::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.ASSESSED_ELEMENT, OverridingObjectsFields.ASSESSED_ELEMENT_WITH_CONTINGENCY, CsaProfileConstants.REQUEST_ASSESSED_ELEMENT_WITH_CONTINGENCY));
}

public Set<AssessedElementWithRemedialAction> getAssessedElementWithRemedialActions() {
return new NcPropertyBagsConverter<>(AssessedElementWithRemedialAction::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.ASSESSED_ELEMENT, OverridingObjectsFields.ASSESSED_ELEMENT_WITH_REMEDIAL_ACTION, CsaProfileConstants.REQUEST_ASSESSED_ELEMENT_WITH_REMEDIAL_ACTION));
}

public Set<CurrentLimit> getCurrentLimits() {
return new NcPropertyBagsConverter<>(CurrentLimit::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.CGMES, OverridingObjectsFields.CURRENT_LIMIT, CsaProfileConstants.REQUEST_CURRENT_LIMIT));
}

public Set<VoltageLimit> getVoltageLimits() {
return new NcPropertyBagsConverter<>(VoltageLimit::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.CGMES, OverridingObjectsFields.VOLTAGE_LIMIT, CsaProfileConstants.REQUEST_VOLTAGE_LIMIT));
}

public Set<VoltageAngleLimit> getVoltageAngleLimits() {
return new NcPropertyBagsConverter<>(VoltageAngleLimit::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.EQUIPMENT_RELIABILITY, OverridingObjectsFields.VOLTAGE_ANGLE_LIMIT, CsaProfileConstants.REQUEST_VOLTAGE_ANGLE_LIMIT));
}

public Set<GridStateAlterationRemedialAction> getGridStateAlterationRemedialActions() {
return new NcPropertyBagsConverter<>(GridStateAlterationRemedialAction::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, OverridingObjectsFields.GRID_STATE_ALTERATION_REMEDIAL_ACTION, CsaProfileConstants.GRID_STATE_ALTERATION_REMEDIAL_ACTION));
}

public Set<TopologyAction> getTopologyActions() {
return new NcPropertyBagsConverter<>(TopologyAction::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, OverridingObjectsFields.TOPOLOGY_ACTION, CsaProfileConstants.TOPOLOGY_ACTION));
}

public Set<RotatingMachineAction> getRotatingMachineActions() {
return new NcPropertyBagsConverter<>(RotatingMachineAction::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, OverridingObjectsFields.ROTATING_MACHINE_ACTION, CsaProfileConstants.ROTATING_MACHINE_ACTION));
}

public Set<ShuntCompensatorModification> getShuntCompensatorModifications() {
return new NcPropertyBagsConverter<>(ShuntCompensatorModification::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, OverridingObjectsFields.SHUNT_COMPENSATOR_MODIFICATION, CsaProfileConstants.SHUNT_COMPENSATOR_MODIFICATION));
}

public Set<TapPositionAction> getTapPositionActions() {
return new NcPropertyBagsConverter<>(TapPositionAction::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, OverridingObjectsFields.TAP_POSITION_ACTION, CsaProfileConstants.TAP_POSITION_ACTION));
}

public Set<StaticPropertyRange> getStaticPropertyRanges() {
return new NcPropertyBagsConverter<>(StaticPropertyRange::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, OverridingObjectsFields.STATIC_PROPERTY_RANGE, CsaProfileConstants.STATIC_PROPERTY_RANGE));
}

public Set<ContingencyWithRemedialAction> getContingencyWithRemedialActions() {
return new NcPropertyBagsConverter<>(ContingencyWithRemedialAction::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, OverridingObjectsFields.CONTINGENCY_WITH_REMEDIAL_ACTION, CsaProfileConstants.REQUEST_CONTINGENCY_WITH_REMEDIAL_ACTION));
}

public Set<Stage> getStages() {
return new NcPropertyBagsConverter<>(Stage::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, CsaProfileConstants.STAGE));
}

public Set<GridStateAlterationCollection> getGridStateAlterationCollections() {
return new NcPropertyBagsConverter<>(GridStateAlterationCollection::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, CsaProfileConstants.GRID_STATE_ALTERATION_COLLECTION));
}

public Set<RemedialActionScheme> getRemedialActionSchemes() {
return new NcPropertyBagsConverter<>(RemedialActionScheme::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, OverridingObjectsFields.REMEDIAL_ACTION_SCHEME, CsaProfileConstants.REMEDIAL_ACTION_SCHEME));
}

public Set<SchemeRemedialAction> getSchemeRemedialActions() {
return new NcPropertyBagsConverter<>(SchemeRemedialAction::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, OverridingObjectsFields.SCHEME_REMEDIAL_ACTION, CsaProfileConstants.REQUEST_SCHEME_REMEDIAL_ACTION));
}

public Set<RemedialActionGroup> getRemedialActionGroups() {
return new NcPropertyBagsConverter<>(RemedialActionGroup::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, CsaProfileConstants.REQUEST_REMEDIAL_ACTION_GROUP));

}

public Set<RemedialActionDependency> getRemedialActionDependencies() {
return new NcPropertyBagsConverter<>(RemedialActionDependency::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.REMEDIAL_ACTION, OverridingObjectsFields.SCHEME_REMEDIAL_ACTION_DEPENDENCY, CsaProfileConstants.REQUEST_REMEDIAL_ACTION_DEPENDENCY));
}

public Set<TapChanger> getTapChangers() {
return new NcPropertyBagsConverter<>(TapChanger::fromPropertyBag).convert(getPropertyBags(CsaProfileKeyword.CGMES, CsaProfileConstants.REQUEST_TAP_CHANGER));
/**
* Returns the set of all the native NC objects of the specified type from the NC profiles
*
* @param nativeType NC type of objects to retrieve
* @param <T> native NC class type
* @return set of native objects
*/
public <T extends NCObject> Set<T> getNativeObjects(Class<T> nativeType) {
if (queriedNativeObjects.containsKey(nativeType)) {
return (Set<T>) queriedNativeObjects.get(nativeType);
}
Query query = Arrays.stream(Query.values()).filter(q -> nativeType.equals(q.getNativeClass())).findFirst().orElseThrow();
Set<T> nativeObjects = getPropertyBags(query).stream().map(pb -> {
try {
return NativeParser.fromPropertyBag(pb, nativeType, query.getDefaultValues());
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException |
InvocationTargetException e) {
throw new OpenRaoException(e);
}
}).collect(Collectors.toSet());
queriedNativeObjects.put(nativeType, nativeObjects);
return nativeObjects;
}

private void setOverridingData(OffsetDateTime importTimestamp) {
overridingData = new HashMap<>();
for (OverridingObjectsFields overridingObject : OverridingObjectsFields.values()) {
addDataFromTripleStoreToMap(overridingData, overridingObject.getRequestName(), overridingObject.getObjectName(), overridingObject.getOverridedFieldName(), overridingObject.getHeaderType(), importTimestamp);
}
Arrays.stream(Query.values()).forEach(query -> addDataFromTripleStoreToMap(overridingData, query, importTimestamp));
}

private void addDataFromTripleStoreToMap(Map<String, String> dataMap, String queryName, String queryObjectName, String queryFieldName, HeaderType headerType, OffsetDateTime importTimestamp) {
PropertyBags propertyBagsResult = queryTripleStore(queryName, tripleStoreCsaProfileCrac.contextNames());
private void addDataFromTripleStoreToMap(Map<String, String> dataMap, Query query, OffsetDateTime importTimestamp) {
if (query.getOverridableAttribute() == null) {
return;
}
PropertyBags propertyBagsResult = queryTripleStore(query.getTitle() + "Overriding", tripleStoreCsaProfileCrac.contextNames());
for (PropertyBag propertyBag : propertyBagsResult) {
if (HeaderType.START_END_DATE.equals(headerType)) {
if (CsaProfileCracUtils.checkProfileKeyword(propertyBag, CsaProfileKeyword.STEADY_STATE_INSTRUCTION) && CsaProfileCracUtils.checkProfileValidityInterval(propertyBag, importTimestamp)) {
String id = propertyBag.getId(queryObjectName);
String overridedValue = propertyBag.get(queryFieldName);
dataMap.put(id, overridedValue);
}
if (!CsaProfileKeyword.CGMES.equals(query.getTargetProfilesKeyword())) {
overrideDataFromSsi(dataMap, query, importTimestamp, propertyBag);
} else {
if (CsaProfileCracUtils.checkProfileKeyword(propertyBag, CsaProfileKeyword.STEADY_STATE_HYPOTHESIS)) {
OffsetDateTime scenarioTime = OffsetDateTime.parse(propertyBag.get(CsaProfileConstants.SCENARIO_TIME));
if (importTimestamp.isEqual(scenarioTime)) {
String id = propertyBag.getId(queryObjectName);
String overridedValue = propertyBag.get(queryFieldName);
dataMap.put(id, overridedValue);
}
overrideDataFromSsh(dataMap, query, importTimestamp, propertyBag);
}
}
}
}

private static void overrideDataFromSsi(Map<String, String> dataMap, Query query, OffsetDateTime importTimestamp, PropertyBag propertyBag) {
if (CsaProfileCracUtils.checkProfileKeyword(propertyBag, CsaProfileKeyword.STEADY_STATE_INSTRUCTION) && CsaProfileCracUtils.checkProfileValidityInterval(propertyBag, importTimestamp)) {
String id = propertyBag.getId(query.getTitle());
String overridingValue = propertyBag.get(query.getOverridableAttribute().getOverridingName());
dataMap.put(id, overridingValue);
}
}

private static void overrideDataFromSsh(Map<String, String> dataMap, Query query, OffsetDateTime importTimestamp, PropertyBag propertyBag) {
OffsetDateTime scenarioTime = OffsetDateTime.parse(propertyBag.get("scenarioTime"));
if (importTimestamp.isEqual(scenarioTime)) {
String id = propertyBag.getId(query.getTitle());
String overridingValue = propertyBag.get(query.getOverridableAttribute().getOverridingName());
dataMap.put(id, overridingValue);
}
}

Expand Down Expand Up @@ -251,8 +193,8 @@ private void clearTimewiseIrrelevantContexts(OffsetDateTime offsetDateTime) {
}

private static boolean checkTimeCoherence(PropertyBag header, OffsetDateTime offsetDateTime) {
String startTime = header.getId(CsaProfileConstants.REQUEST_HEADER_START_DATE);
String endTime = header.getId(CsaProfileConstants.REQUEST_HEADER_END_DATE);
String startTime = header.getId(CsaProfileConstants.START_DATE);
String endTime = header.getId(CsaProfileConstants.END_DATE);
return CsaProfileCracUtils.isValidInterval(offsetDateTime, startTime, endTime);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2024, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.powsybl.openrao.data.cracio.csaprofiles;

import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.data.cracio.csaprofiles.nc.NCObject;
import com.powsybl.triplestore.api.PropertyBag;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.RecordComponent;
import java.util.Arrays;
import java.util.Map;

/**
* @author Thomas Bouquet {@literal <thomas.bouquet at rte-france.com>}
*
* Utility class that provides a generic template to query native objects
* in NC profiles and to cast the results to native NC objects.
*/
public final class NativeParser {

private NativeParser() {
}

private static Object parseStringValue(String value, Class<?> targetType) {
if (value == null || String.class.equals(targetType)) {
return value;
} else if (Boolean.class.equals(targetType)) {
if ("true".equalsIgnoreCase(value)) {
return true;
} else if ("false".equalsIgnoreCase(value)) {
return false;
} else {
return null;
}
} else if (Double.class.equals(targetType)) {
return Double.parseDouble(value);
} else if (Integer.class.equals(targetType)) {
return Integer.parseInt(value);
} else {
throw new OpenRaoException("Unsupported type %s".formatted(targetType.getName()));
}
}

private static String getMrid(PropertyBag propertyBag, Class<?> nativeClass) {
String propertyBagName = Character.toLowerCase(nativeClass.getSimpleName().charAt(0)) + nativeClass.getSimpleName().substring(1);
return propertyBag.getId(propertyBagName);
}

public static <T extends NCObject> T fromPropertyBag(PropertyBag propertyBag, Class<T> nativeClass, Map<String, Object> defaultValues) throws IllegalArgumentException, OpenRaoException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// Ensure the class is a record
if (!nativeClass.isRecord()) {
throw new IllegalArgumentException("Provided class is not a record");
}

// Get the record's components (fields)
RecordComponent[] components = nativeClass.getRecordComponents();

// Prepare an array to hold the values for the record's constructor
Object[] constructorArgs = new Object[components.length];

// Loop through the components and extract values from the property bag
for (int i = 0; i < components.length; i++) {
RecordComponent component = components[i];
if ("mrid".equals(component.getName())) {
constructorArgs[i] = getMrid(propertyBag, nativeClass);
} else {
Object parsedValue = parseStringValue(propertyBag.getId(component.getName()), component.getType());
if (parsedValue == null) {
parsedValue = defaultValues.get(component.getName());
}
constructorArgs[i] = parsedValue;
}
}

// Find the canonical constructor of the record class
Constructor<T> constructor = nativeClass.getDeclaredConstructor(
// Get the types of the components (this matches the constructor signature)
Arrays.stream(components)
.map(RecordComponent::getType)
.toArray(Class<?>[]::new)
);

// Create and return a new instance of the record
return constructor.newInstance(constructorArgs);
}
}
Loading
Loading