Skip to content

Commit

Permalink
Merge pull request #297 from ncats/fixrender
Browse files Browse the repository at this point in the history
Allow structure renderer settings to be supplied in the application config
  • Loading branch information
ChemMitch authored Nov 6, 2023
2 parents f80e52c + 47da798 commit c9f3f71
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 28 deletions.
2 changes: 1 addition & 1 deletion gsrs-module-substances-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<dependency>
<groupId>gov.nih.ncats</groupId>
<artifactId>molwitch-renderer</artifactId>
<version>1.0.14-SNAPSHOT</version>
<version>1.0.15-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>gov.nih.ncats</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package gsrs.module.substance;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.annotation.JsonIgnore;

import gov.nih.ncats.molvec.internal.util.CachedSupplier;
import gov.nih.ncats.molwitch.renderer.RendererOptions;
import gsrs.module.substance.RendererOptionsConfig.FullRenderOptions;
import gsrs.module.substance.RendererOptionsConfig.FullRenderOptions.FullRenderOptionsBuilder;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Configuration
@ConfigurationProperties("gsrs.renderers")
@Data
@Slf4j
public class GSRSRendererConfiguration {

private String selected;

private LinkedHashMap<Integer,Map> list;

@JsonIgnore
@Getter(value=AccessLevel.NONE)
@Setter(value=AccessLevel.NONE)
private CachedSupplier<Map<String,FullRenderOptions>> _fullRenderer = CachedSupplier.of(()->{
Map<String, FullRenderOptions> renderMap = new HashMap<>();

int i=0;
if(list!=null) {
for(Map m:list.values()) {
String name = m.getOrDefault("name", "").toString();
FullRenderOptionsBuilder baseBuilder = FullRenderOptions.builder();
if(name==null || name.length()==0) {
log.error("Render settings must have names, gsrs.renderers.list[%i] does not have a name. That render config will be skipped.", i);
continue;
}

Map<String, Object> renderer = (Map<String, Object>) m.get("renderer");
if(renderer==null || !(renderer instanceof Map)) {
log.error("Render settings must have 'renderer' setting, gsrs.renderers.list[%i].renderer is not expected format.", i);
continue;
}

if(renderer.get("preset")!=null) {
String preset=renderer.get("preset").toString();

FullRenderOptions opt=Optional.ofNullable(renderMap.get(preset)).orElseGet(()->getDefaultRendererOptionsByName(preset).orElse(null));


if(opt==null) {
log.warn("Render settings preset '%s' not found as a valid preset. The default render config will be used instead.", preset);
opt = FullRenderOptions.builder().build();
}
baseBuilder=opt.toBuilder();
}
Map<String,Object> options = (Map<String,Object>) renderer.get("options");
if(options!=null) {
RendererOptions ropts= baseBuilder.build().getOptions();
ropts=ropts.changeSettings(options);
baseBuilder=baseBuilder.options(ropts);
}

FullRenderOptionsBuilder baseBuilderFinal = baseBuilder;

Optional.ofNullable(renderer.get("add-shadow")).ifPresent(ss->{
baseBuilderFinal.showShadow("true".equalsIgnoreCase(ss.toString()));
});
Optional.ofNullable(renderer.get("add-border")).ifPresent(ss->{
baseBuilderFinal.addBorder("true".equalsIgnoreCase(ss.toString()));
});
Optional.ofNullable(renderer.get("color-bg")).ifPresent(ss->{
baseBuilderFinal.colorBg(ss.toString());
});
Optional.ofNullable(renderer.get("color-border")).ifPresent(ss->{
baseBuilderFinal.colorBorder(ss.toString());
});


renderMap.put(name,baseBuilderFinal.build());
i++;
}
}
return renderMap;
});



private Optional<FullRenderOptions> getDefaultRendererOptionsByName(String name){
if(name !=null) {
if ("INN".equalsIgnoreCase(name)) {
return Optional.ofNullable(FullRenderOptions.builder().options(RendererOptions.createINNLike()).build());
}
if ("USP".equalsIgnoreCase(name)) {
return Optional.ofNullable(FullRenderOptions.builder().options(RendererOptions.createUSPLike())
.showShadow(false)
.build());
}
if ("DEFAULT".equalsIgnoreCase(name)) {
return Optional.ofNullable(FullRenderOptions.builder().options(RendererOptions.createDefault()).build());
}
String lowerName = name.toLowerCase();
if (lowerName.contains("ball") && lowerName.contains("stick")) {
return Optional.ofNullable(FullRenderOptions.builder().options(RendererOptions.createBallAndStick()).build());
}
}
return Optional.empty();
}

public Optional<FullRenderOptions> getFullRendererOptionsByName(String name){
//TODO: not sure the CONF part is needed anymore
if(name !=null && !("CONF".equalsIgnoreCase(name))) {
return Optional.ofNullable(getDefaultRendererOptionsByName(name)
.orElseGet(()->_fullRenderer.get().get(name)));
}
return Optional.empty();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,37 @@

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.databind.ObjectMapper;

import gov.nih.ncats.common.util.CachedSupplier;
import gov.nih.ncats.molwitch.renderer.ARGBColor;
import gov.nih.ncats.molwitch.renderer.ColorPalette;
import gov.nih.ncats.molwitch.renderer.RendererOptions;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Configuration
@Data
@Slf4j
public class RendererOptionsConfig {


@Autowired
GSRSRendererConfiguration rendererConf;


@Value("${substance.renderer.configPath:#{null}}")
private String rendererOptionsJsonFilePath;
@Value("${substance.renderer.style:#{null}}")
Expand All @@ -34,23 +47,37 @@ public static class FullRenderOptions{
private RendererOptions options;
@Builder.Default
private boolean showShadow=true;
@Builder.Default
private boolean addBorder=false;
private String colorBg;
private String colorBorder;


public FullRenderOptions copy() {
return FullRenderOptions.builder().options(options.copy()).showShadow(showShadow).build();
return toBuilder()
.build();
}

public FullRenderOptionsBuilder toBuilder(){
return FullRenderOptions.builder()
.options(options.copy())
.showShadow(showShadow)
.addBorder(addBorder)
.colorBg(colorBg)
.colorBorder(colorBorder);
}
}

private CachedSupplier<FullRenderOptions> rendererSupplier = CachedSupplier.of(()->{
if(legacyStyle !=null){
FullRenderOptions opt = getRendererOptionsByName(legacyStyle);
FullRenderOptions opt = rendererConf.getFullRendererOptionsByName(legacyStyle).orElse(null);

if(opt !=null){
return opt;
}
}
if(style !=null){
FullRenderOptions opt = getRendererOptionsByName(style);
FullRenderOptions opt = rendererConf.getFullRendererOptionsByName(style).orElse(null);
if(opt !=null){
return opt;
}
Expand All @@ -60,9 +87,11 @@ public FullRenderOptions copy() {
Resource optionsJson = new ClassPathResource(rendererOptionsJsonFilePath);
if(optionsJson !=null) {
try (InputStream in = optionsJson.getInputStream()) {
return FullRenderOptions.builder().options(mapper.readValue(in, RendererOptions.class)).build();
RendererOptions options= RendererOptions.createFromMap((Map<String, ?>) mapper.readValue(in, Map.class));

return FullRenderOptions.builder().options(options).build();
} catch (IOException e) {
e.printStackTrace();
log.error("Error deserializing renderer options");
}
}
}
Expand All @@ -73,24 +102,4 @@ public FullRenderOptions getDefaultRendererOptions(){
return rendererSupplier.get();
}

private FullRenderOptions getRendererOptionsByName(String name){
if(name !=null && !("CONF".equalsIgnoreCase(name))) {
if ("INN".equalsIgnoreCase(name)) {
return FullRenderOptions.builder().options(RendererOptions.createINNLike()).build();
}
if ("USP".equalsIgnoreCase(name)) {
return FullRenderOptions.builder().options(RendererOptions.createUSPLike())
.showShadow(false)
.build();
}
if ("DEFAULT".equalsIgnoreCase(name)) {
return FullRenderOptions.builder().options(RendererOptions.createDefault()).build();
}
String lowerName = name.toLowerCase();
if (lowerName.contains("ball") && lowerName.contains("stick")) {
return FullRenderOptions.builder().options(RendererOptions.createBallAndStick()).build();
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
ConfigBasedDefinitionalElementConfiguration.class, ConfigBasedDefinitionalElementFactory.class,
LegacyGinasAppController.class,
NameStandardizerConfiguration.class,
ProxyConfiguration.class, StructureResolverService.class, StructureResolverServiceConfiguration.class,
ProxyConfiguration.class,
GSRSRendererConfiguration.class,
StructureResolverService.class, StructureResolverServiceConfiguration.class,
SubstanceDataConfiguration.class,
StructureResolverController.class,
SubstanceSpreadsheetExporterConfiguration.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,18 @@ public byte[] renderChemical (Structure struc, Chemical chem, String format,
// }


if (fullRendererOptions.isAddBorder()) {
renderer.setBorderVisible(true);
if(fullRendererOptions.getColorBorder()!=null) {
renderer.setBorderColorARGB(fullRendererOptions.getColorBorder());
}
}

if (fullRendererOptions.getColorBg()!=null) {
renderer.setBorderColorARGB(fullRendererOptions.getColorBg());
}


ByteArrayOutputStream bos = new ByteArrayOutputStream();

if (parameters != null && parameters.hasValuesForAll()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void run(SchedulerPlugin.JobStats stats, SchedulerPlugin.TaskListener l)
try{
adminService.runAs(adminAuth, (Runnable)() -> {
TransactionTemplate tx = new TransactionTemplate(platformTransactionManager);
tx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
// tx.setPropagationBehavior(TransactionDefinition.);
try {
tx.executeWithoutResult(status -> {
structureRepository.findById(id).ifPresent(s -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -753,3 +753,66 @@ gsrs.processing-strategy = {
{"regex": "E4562650", "userRoles": ["SuperUpdate", "SuperDataEntry"], "newMessageType": "WARNING"}
]
}










# This shows how special render settings can be applied
# at a pretty deep explicit level. This is ported over largely from how
# it was done in GSRS 2.8
#
#
# 1. Supports embedded JSON options definitions for the structure renderer
# 2. Supports naming styles for use
# 3. Supports using previously named styles and making variations of them
#
gsrs.renderers.list=[
{
"name" : "CLEAN",
"renderer" :{
"preset": "USP", //Note this part
"options" : {
"PROP_KEY_DRAW_GREYSCALE" : false,
"ATOM_LABEL_FONT_FRACTION" : 0.47918,
"ATOM_LABEL_BOND_GAP_FRACTION" :1.02,
"BOND_STROKE_WIDTH_FRACTION" : 0.032,
"BOND_DOUBLE_GAP_FRACTION": 0.1995,
"BOND_STEREO_WEDGE_ANGLE" : 0.13659,
"BOND_STEREO_DASH_NUMBER" :8,
"SUBSCRIPT_Y_DISPLACEMENT_FRACTION" : 0.17,
"DRAW_WEDGE_AS_POINT" : false,
"DRAW_STEREO_WEDGE_JOIN" : true,
"DRAW_STEREO_LAST_DASH_ON_NON_SYMBOLS" : false,
"colorPalette" : {
"atomColors" : {
"C" : "FFFF0000" // red carbons (ugly)
}
}
},
"add-shadow" : true,
"add-border" : false
}
},
{
"name" : "MONSTRUOUS",
"renderer" :{
"preset": "CLEAN", //Note this part
"options" : {
"BOND_STROKE_WIDTH_FRACTION" : 0.64
},
"add-shadow" : false,
"add-border" : false
}
}
]

# Here, you can specify the main renderer style to use, which can be one of the default supported cases
# or can be one of the specified cases in the list above.

#gsrs.renderers.selected="CLEAN1"
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class CalculateMatchablesScheduledTask extends ScheduledTaskInitializer{

@Autowired
private PlatformTransactionManager platformTransactionManager;

SubstanceStagingAreaEntityService substanceStagingAreaEntityService = new SubstanceStagingAreaEntityService();

@Autowired
Expand Down

0 comments on commit c9f3f71

Please sign in to comment.