Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
10 changes: 10 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@

2.3.8

* Write out crosslinker stub information to mzIdentML
* updated to XLMOD java library 1.1 to reduce "unknown modifications"
* BugFix: mzIdentML 1.3 empty protein descriptions no longer written out
* BugFix: mzIdentML 1.3 export still had some mzIdentML 1.2 namespace attributes
* currently using a modified version of jmzIdentML (pull request pending)
* allow matching to crosslinker without mass definition (e.g. DSSO)
* BugFix: mzIdentML export for non-covalent peptide pairs

2.3.7

* BugFix: xiview csv file can miss data
Expand Down
24 changes: 12 additions & 12 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.rappsilberlab</groupId>
<artifactId>xiFDR</artifactId>
<version>2.3.7</version>
<version>2.3.8</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
Expand All @@ -25,11 +25,6 @@
<scope>runtime</scope>
<type>jar</type>
</dependency-->
<dependency>
<groupId>org.rappsilber</groupId>
<artifactId>XLMOD</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>uk.ac.liv</groupId>
<artifactId>mzidlib</artifactId>
Expand Down Expand Up @@ -104,16 +99,21 @@
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>uk.ac.ebi.jmzidml</groupId>
<artifactId>jmzidentml</artifactId>
<version>1.2.13</version>
</dependency>
<dependency>
<groupId>rappsilber</groupId>
<artifactId>xiSEARCH</artifactId>
<version>1.8.7</version>
</dependency>
<dependency>
<groupId>uk.ac.ebi.jmzidml</groupId>
<artifactId>jmzidentml</artifactId>
<version>1.2.13-lf</version>
</dependency>
<dependency>
<groupId>org.rappsilber</groupId>
<artifactId>XLMOD</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down Expand Up @@ -170,5 +170,5 @@
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<description>Application for FDR estimation cross-linking massspectrometry data </description>
<name>xiFDR-2.3.7</name>
<name>xiFDR-2.3.8</name>
</project>
2 changes: 1 addition & 1 deletion src/main/java/org/rappsilber/config/LocalProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public static Object setFolder(String key, String path) {
*/
public static synchronized Object setProperty(String key, String value) {
String old = localProperties.getProperty(key);
if ((old == null && value != null) || old.contentEquals(value)) {
if ((old == null && value != null) || (old != null && old.contentEquals(value))) {

Copilot AI Jul 4, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition uses old.contentEquals(value), so the property is only set when the old and new values are identical; this should likely be !old.contentEquals(value) to detect and persist changed values.

Suggested change
if ((old == null && value != null) || (old != null && old.contentEquals(value))) {
if ((old == null && value != null) || (old != null && !old.contentEquals(value))) {

Copilot uses AI. Check for mistakes.
Object ret = localProperties.setProperty(key, value);
try {
localProperties.store(new FileOutputStream(userPropertiesFile), "XLink local properties file");
Expand Down
15 changes: 6 additions & 9 deletions src/main/java/org/rappsilber/fdr/MZIdentXLFDR.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,23 @@
package org.rappsilber.fdr;

import org.rappsilber.fdr.result.FDRResult;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.rappsilber.fdr.OfflineFDR;
import org.rappsilber.fdr.entities.PSM;
import org.rappsilber.fdr.entities.PeptidePair;
import org.rappsilber.fdr.utils.StreamReplaceWriter;
import uk.ac.ebi.jmzidml.MzIdentMLElement;
import uk.ac.ebi.jmzidml.model.mzidml.AbstractParam;
import uk.ac.ebi.jmzidml.model.mzidml.AnalysisCollection;
import uk.ac.ebi.jmzidml.model.mzidml.AnalysisProtocolCollection;
import uk.ac.ebi.jmzidml.model.mzidml.AnalysisSoftware;
Expand All @@ -49,19 +48,17 @@
import uk.ac.ebi.jmzidml.model.mzidml.Param;
import uk.ac.ebi.jmzidml.model.mzidml.PeptideEvidence;
import uk.ac.ebi.jmzidml.model.mzidml.PeptideEvidenceRef;
import uk.ac.ebi.jmzidml.model.mzidml.PeptideHypothesis;
import uk.ac.ebi.jmzidml.model.mzidml.ProteinAmbiguityGroup;
import uk.ac.ebi.jmzidml.model.mzidml.ProteinDetectionHypothesis;
import uk.ac.ebi.jmzidml.model.mzidml.ProteinDetectionList;
import uk.ac.ebi.jmzidml.model.mzidml.Provider;
import uk.ac.ebi.jmzidml.model.mzidml.SequenceCollection;
import uk.ac.ebi.jmzidml.model.mzidml.SpectraData;
import uk.ac.ebi.jmzidml.model.mzidml.SpectrumIdentificationItem;
import uk.ac.ebi.jmzidml.model.mzidml.SpectrumIdentificationItemRef;
import uk.ac.ebi.jmzidml.model.mzidml.SpectrumIdentificationList;
import uk.ac.ebi.jmzidml.model.mzidml.SpectrumIdentificationResult;
import uk.ac.ebi.jmzidml.model.mzidml.SubstitutionModification;
import uk.ac.ebi.jmzidml.model.mzidml.UserParam;
import uk.ac.ebi.jmzidml.model.utils.MzIdentMLVersion;
import uk.ac.ebi.jmzidml.xml.io.MzIdentMLMarshaller;
import uk.ac.ebi.jmzidml.xml.io.MzIdentMLUnmarshaller;

Expand Down Expand Up @@ -704,11 +701,11 @@ public void writeMZIdentML(String mzidFileName, FDRResult result) {
if (!outFile.endsWith(".mzid")) {
outFile = outFile + ".mzid";
}
FileWriter fwriter = new FileWriter(outFile);
StreamReplaceWriter writer = new StreamReplaceWriter(fwriter, "xmlns=\"http://psidev.info/psi/pi/mzIdentML/1.1\"", "");
FileOutputStream fwriter = new FileOutputStream(outFile);
OutputStreamWriter writer = new OutputStreamWriter(fwriter, "UTF-8");

MzIdentMLMarshaller marshaller;
marshaller = new MzIdentMLMarshaller();
marshaller = new MzIdentMLMarshaller(MzIdentMLVersion.Version_1_3);

writer.write(marshaller.createXmlHeader() + "\n");

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/rappsilber/fdr/calculation/Boost.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public MaximisingStatus maximiseInner(FDRSettings fdrSettings, OfflineFDR.FDRLev

try {
int steps = settings.getBoostingSteps();
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
double maxDelta = 1;
double maxPeptideCoverage = 1;

Expand Down
37 changes: 29 additions & 8 deletions src/main/java/org/rappsilber/fdr/dataimport/Xi2Xi1Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand All @@ -30,7 +27,6 @@
import java.util.logging.Logger;
import org.json.simple.parser.ParseException;
import org.json.simple.parser.JSONParser;
import org.rappsilber.utils.RArrayUtils;
import org.rappsilber.utils.ms.Composition;
import rappsilber.config.AbstractRunConfig;
import rappsilber.config.ConfigurationParserException;
Expand All @@ -42,7 +38,6 @@
import rappsilber.ms.sequence.AminoAcid;
import rappsilber.ms.sequence.AminoModification;
import rappsilber.ms.sequence.digest.AAConstrainedDigestion;
import rappsilber.ms.sequence.ions.AIon;


/**
Expand All @@ -51,8 +46,6 @@
*/
public class Xi2Xi1Config extends AbstractRunConfig{
HashMap<String, Double> default_xl_masses = new HashMap<>();
{
}
HashMap<String, CrossLinker> default_xl_xi1 = new HashMap<>();
HashMap<String, Xi2Crosslinker> default_xl_xi2 = new HashMap<>();
public boolean isModX = true;
Expand Down Expand Up @@ -97,12 +90,19 @@ public class Xi2Xi1Config extends AbstractRunConfig{
}


/**
* Java representation of the xiSEARCH2 crosslinker definition.
* Only the here needed information are retained
*/
public class Xi2Crosslinker {
public String name;
public Double mass ;
String[][] specificity = new String[2][];


/**
* initialise just with name and get the rest from default definitions.
* @param name Name of the crosslinker
*/
public Xi2Crosslinker(String name) {
this.name = name;
if (default_xl_masses.containsKey(name.toUpperCase())) {
Expand All @@ -112,17 +112,32 @@ public Xi2Crosslinker(String name) {
}
}

/**
* Initialise by name and mass.
* @param name Name of the crosslinker
* @param mass mass of the reacted crosslinker
*/
public Xi2Crosslinker(String name, double mass) {
this.name = name;
this.mass = mass;
}

/**
* Initialise by name, mass, and specificity.
* @param name Name of the crosslinker
* @param mass mass of the reacted crosslinker
* @param specificity where can the crosslinker react
*/
public Xi2Crosslinker(String name, double mass, String[][] specificity) {
this.name = name;
this.mass = mass;
this.specificity = specificity;
}

/**
* initialise based on a json crosslinker defintion derived map
* @param m
*/
public Xi2Crosslinker(Map m) {
this.name = m.get("name").toString();
this.mass = (Double) m.get("mass");
Expand Down Expand Up @@ -154,6 +169,12 @@ public Xi2Crosslinker(Map m) {
}
}

/**
* Convert to a xiSEARCH1 crosslinker definition.
* @return
* @throws java.text.ParseException
* @throws ConfigurationParserException
*/
public String toXi1Crosslinker() throws java.text.ParseException, ConfigurationParserException {
StringBuilder sb = new StringBuilder("crosslinker:AsymetricSingleAminoAcidRestrictedCrossLinker:NAME:");
sb.append(this.name);
Expand Down
13 changes: 10 additions & 3 deletions src/main/java/org/rappsilber/fdr/entities/Protein.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
package org.rappsilber.fdr.entities;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.rappsilber.fdr.utils.FDRGroupNames;
import org.rappsilber.utils.DoubleArrayList;
import java.util.regex.*;

/**
* Represents a single protein.
Expand Down Expand Up @@ -53,8 +55,7 @@ public class Protein extends AbstractFDRElement<Protein> {//implements Comparabl
public static String DECOY_PREFIX = null;
String zero = ""+(char)0;
private Pattern zerosplit = Pattern.compile(zero);
private Pattern spacesplit = Pattern.compile(" ");

private Pattern spacesplit = Pattern.compile("^\\s*(\"[^\"]*\"|'[^']*'|\\([^)]*\\)|[^\\s]+)");


private String fdrgroup = null;
Expand Down Expand Up @@ -132,7 +133,13 @@ public Protein(long id, String accession, String description, boolean isDecoy, b
this.name = zerosplit.split(description)[1];
this.description = zerosplit.split(description)[0];
} else {
this.name = spacesplit.split(description)[0];
// try parsing a name from description
Matcher m = spacesplit.matcher(description);
if (m.find()) {
this.name = m.group(1);
} else {
this.name = this.description;
}
}
}

Expand Down
Loading