Skip to content

Commit 44a5ff1

Browse files
committed
v5.8.2
Small changes for the input
1 parent 46a1c2f commit 44a5ff1

27 files changed

Lines changed: 489 additions & 244 deletions

docs/Release.html

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,30 @@ <h3>Summary of recent major releases</h3>
6868
<tr><td><a href="#v540">v5.4.0</a><td>(06-Apr-23)<td>Improved <ttx>Cluster Hit</ttx> algorithm <ttx>Algo1</ttx> for the detection of gene homology.
6969
</table>
7070

71+
<h3>Release: v5.8.2 (1-Apr-2026)</h3>
72+
<p>Small changes for the input.
73+
<ul>
74+
<li>Bug fix: If no category had been previously defined, <ttp>symap</ttp> would not
75+
bring up the <ttl>Project Parameters</ttl> window.
76+
<p><li>Input files:
77+
<ul>
78+
<li><ttp>xToSymap</ttp>: For NCBI files, an input sequence is considered a
79+
chromosome if the header line <tt>seqid</tt> starts with NC_. Now it will also be considered a chromosome
80+
if the header line contains the word "chromosome".
81+
<p><li><ttl>Load Project</ttl>:
82+
<ul><li>A sequence identifier was restricted to letters and numbers; now it can also include
83+
"_", "-" and ".".
84+
<li>A secondary name can now be associated with the
85+
sequence identifier, see <a href="./input/index.html#seqprep">Sequence files</a>.
86+
Both identifiers will be shown in <ttl>View</ttl>. This requires a small database
87+
change, but it is done on <ttl>Load Project</ttl>.
88+
</ul>
89+
</ul>
90+
<p>
91+
<li><ttp>Dot Plot</ttp>: When the mouse is over a chr-chr cell in the whole genome view, the Chromosome names will be shown.
92+
If either has a secondary name, it will be shown too.
93+
</ul>
94+
7195
<h3>Release: v5.8.1 (11-Mar-2026)</h3>
7296
Two small improvements to the <ttl>Alignment&amp;Synteny</ttl>.
7397
<p><ul>

docs/SystemGuide.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,10 @@ <h4>Timings</h4>
426426
<tr><td style="white-space: nowrap;">Hsa x Mus&nbsp;<sup>b</sup>
427427
<td style="text-align: right;">8h:03m<td style="text-align: right;">0m:37s
428428
<td>&nbsp;<td style="text-align: center;">&nbsp;&nbsp;3Gb x 2.7Gb<td>&nbsp;MASKED, 84 alignments, <b>v5.8.1</b>
429-
<tr><td style="white-space: nowrap;">Hsa x Pan&nbsp;<td>22h:48m<td style="text-align: right;">9m:31s
430-
<td>&nbsp;<td style="text-align: center;">3Gb x 3Gb<td>&nbsp;MASKED, closely related, 600 alignments, <ttl>!Concat</ttl>
429+
430+
<tr><td style="white-space: nowrap;">Hsa x Pan&nbsp;<td>22h:48m<br>16h:40m<td style="text-align: right;">9m:31s<br>9m:23s
431+
<td>&nbsp;<td style="text-align: center;">3Gb x 3Gb<td>&nbsp;MASKED, closely related, 600 alignments, <ttl>!Concat</ttl><br>&nbsp;84 alignments, v5.8.1
432+
431433
<tr><td style="white-space: nowrap;">Hsa x self&nbsp;<td style="text-align: right;">7h:45m<td style="text-align: right;">8m:28s
432434
<td>&nbsp;<td style="text-align: center;">3Gb x 3Gb<td>&nbsp;276 alignments, NT
433435

docs/img/arabSelf.png

-1.11 KB
Loading

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
<li>It can align a draft genome to a fully sequenced genome and order the draft (see <a href="./peach.html">Peach</a>).
6565
<li>The query and display is designed for the comparison of a few genomes at a time (i.e. 2-4).
6666
</ul>
67-
<p>Latest SyMAP release: v5.8.1 (11-March-2026), see <a href="./Release.html">Release Notes</a>.
67+
<p>Latest SyMAP release: v5.8.1 (1-April-2026), see <a href="./Release.html">Release Notes</a>.
6868
</div>
6969

7070
<p><table><tr>

docs/input/img/loaded.png

15.9 KB
Loading

docs/input/img/viewA.png

30.1 KB
Loading

docs/input/index.html

Lines changed: 130 additions & 74 deletions
Large diffs are not rendered by default.

docs/input/ncbi.html

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,19 @@ <h2>Convert files</h2>
145145
<td><a href="#scaf">Scaffolds</a>
146146
<td class="colrt"><a href="#top">Go to top</a>
147147
</table>
148-
<p>The following instructions will use <i>Brassica oleracea</i> (wild cabbage) as an example.
148+
149+
<p>The following instructions will use the <i>Brassica oleracea</i> (wild cabbage) as an example.
150+
151+
<ol type="I">
152+
<li>If you have NCBI <tt>.fna</tt> and <tt>.gff</tt> files, do the following:
153+
<ol>
154+
<li>Go to the <tt>symap_5/data/seq</tt> directory.
155+
<li>Make a subdirectory for your species, e.g. <tt>mkdir cabbN</tt>
156+
<li>Move your <tt>.fna</tt> and <tt>.gff</tt> files to this directory.
157+
</ol>
158+
<p>
159+
<li>If you have the <tt>ncbi_dataset.zip</tt> file as discussed above in <a href="#dl">Download</a>,
160+
do the following.
149161
<ol>
150162
<li>Go to the <tt>symap_5/data/seq</tt> directory.
151163
<p>
@@ -165,26 +177,23 @@ <h2>Convert files</h2>
165177
inflating: ncbi_dataset/data/GCF_000695525.1/genomic.gff
166178
inflating: ncbi_dataset/data/dataset_catalog.json
167179
</pre>
168-
<li>Start the <a href="./index.html#if" class="ext" target="_blank">xToSymap</a> program.
180+
181+
</ol>
182+
</ol>
183+
Start the <a href="./index.html#if" class="ext" target="_blank">xToSymap</a> program.
169184
<ul><li>
170185
Select the appropriate xToSymap NCBI options (described below).
171186
<li>Then select <ttb>Convert</ttb>.</ul>
172-
</ol>
173187

174188
The program will output statistics to the terminal and a <a href="./logs/cnvCabbN.html" class="ext" target="_blank">log file</a>.
175-
The <ttx>cabbN</ttx> directory will contain the following:
189+
The <tt>symap_5/data/seq/cabbn</tt> directory will contain the following new directories and files:
176190
<p>
177191
<pre>
178-
symap_5/data/seq/cabbN&gt; ls -hlG
179-
total 264008
180-
-rw-------@ 1 cari staff 1.6K Jul 23 2024 README.md
181-
drwxr-xr-x 4 cari staff 128B Jul 23 09:54 annotation/
182-
drwxr-xr-x@ 3 cari staff 96B Jul 23 08:19 ncbi_dataset/
183-
-rw-r--r--@ 1 cari staff 126M Jul 23 07:11 ncbi_dataset.zip
184-
drwxr-xr-x 3 cari staff 96B Jul 23 09:54 sequence/
192+
annotation/anno.gff annotation/gap.gff sequence/genomic.fna
185193
</pre>
194+
186195
You may remove everything but <tt>annotation/</tt> and <tt>sequence/</tt>.
187-
However, you may want to keep the original <tt>data/seq/cabb/ncbi_dataset</tt>.
196+
However, you may want to keep the original <tt>.fna</tt> and <tt>.gff</tt> files.
188197

189198
<!------------------------------------------------------->
190199
<a id="opts"></a>
@@ -237,7 +246,8 @@ <h3>xToSymap NCBI Options</h3>
237246
start with the prefix.
238247
Then the following rules 2-4 are applied to the non-filtered sequences:
239248
<br>&nbsp;
240-
<li>Chromosomes: The name starts with 'NC_'.
249+
<li>Chromosomes: The name starts with 'NC_' or the header line contains the word "chromosome"
250+
(this 2nd condition was added in v5.8.2).
241251
<ul>
242252
<li>The exception is that Mt/Pt chromosomes will not be output unless <ttl>Mt/Pt</ttl> is selected.
243253
<br>Mt/Pt: header line contains the word 'mitochondrion', 'mitochondrial', 'plastid' or 'chloroplast'.

java/src/backend/AnnotLoadMain.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
*/
2929

3030
public class AnnotLoadMain {
31+
private static final int maxPrtErr = SeqLoadMain.maxPrtErr;
3132
private final String idKey = "ID"; // Gene and mRNA
3233
private final String parentKey = "Parent"; // mRNA and Exon
3334

@@ -135,9 +136,9 @@ private void loadFile(File f) throws Exception {
135136
if (fs.length < 9) {
136137
ErrorCount.inc();
137138
numParseErrors++;
138-
if (numParseErrors <= 3) {
139+
if (numParseErrors <= maxPrtErr) {
139140
plog.msgToFile("*** Parse: expecting at least 9 tab-delimited fields in gff file at line " + lineNum);
140-
if (numParseErrors >= 3) plog.msgToFile("*** Suppressing further parse errors");
141+
if (numParseErrors >= maxPrtErr) plog.msgToFile("*** Suppressing further parse errors");
141142
}
142143
continue; // skip this annotation
143144
}
@@ -192,11 +193,11 @@ else if (isExon) {
192193

193194
/** Process for write **/
194195
// Chromosome idx
195-
grpIdx = mProj.getGrpIdxRmPrefix(chr);
196+
grpIdx = mProj.getGrpIdx(chr); // Was checking for valid ID, but if its in the database, then it is. CAS582
196197
if (grpIdx < 0) {// this is not an error; can happen if scaffolds have been filtered out
197198
if (!noGrpSet.contains(chr)) {
198-
if (noGrpSet.size() < 3) plog.msgToFile("+++ Gene on sequence '" + chr + "'; sequence is not loaded - ignore");
199-
else if (noGrpSet.size() == 3) plog.msgToFile("+++ Suppressing further warnings of no loaded sequence");
199+
if (noGrpSet.size() < maxPrtErr) plog.msgToFile("+++ Gene on sequence '" + chr + "'; sequence is not loaded - ignore");
200+
else if (noGrpSet.size() == maxPrtErr) plog.msgToFile("+++ Suppressing further warnings of no loaded sequence");
200201
if (noGrpSet.size()==0) System.out.println("Valid names: " + mProj.getValidGroup());
201202
noGrpSet.add(chr);
202203
}
@@ -435,7 +436,7 @@ else if (f.isDirectory()) {
435436
}
436437
}
437438
}
438-
if (saveAnnoDir!="") {// print on View
439+
if (!saveAnnoDir.isBlank()) {// print on View; CAS582 was !=""
439440
modDirDate = new File(saveAnnoDir).lastModified();
440441
mProj.saveProjParam("proj_anno_date", Utils.getDateStr(modDirDate));
441442
mProj.saveProjParam("proj_anno_dir", saveAnnoDir);

java/src/backend/SeqLoadMain.java

Lines changed: 112 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@
2626
*/
2727
public class SeqLoadMain {
2828
static int projIdx = 0;
29+
protected static final int maxPrtErr=2;
2930
private static final int CHUNK_SIZE = Constants.CHUNK_SIZE;
3031
private static final int MAX_GRPS = BlockViewFrame.MAX_GRPS;
3132
private static final int MAX_COLORS = BlockViewFrame.maxColors;
33+
private static final int maxLenName = 20; // in input/index.html secondary name
34+
3235
private Mproject mProj;
3336
private DBconn2 tdbc2=null;
3437
private ProgressDialog plog;
@@ -38,6 +41,7 @@ public class SeqLoadMain {
3841
private long modDirDate=0;
3942
private int totalnSeqs=0, cntFile=0, totalSeqIgnore=0, totalBasesWritten=0;
4043
private Vector<String> grpList = new Vector<String>();
44+
private int fileType=0, iNCBI=1, iEns=2;
4145

4246
protected boolean run(DBconn2 dbc2, ProgressDialog plog, Mproject mProj) throws Exception {
4347
try {
@@ -174,6 +178,8 @@ else if (f.isDirectory()) {
174178
*/
175179
private boolean loadSeqFiles() {
176180
try {
181+
tdbc2.tableCheckAddColumn("xgroups", "labname", "VARCHAR(40) NOT NULL", "fullname"); // CAS582 backwards
182+
177183
String prefix = mProj.getGrpPrefix();
178184
if (prefix.contentEquals("")) plog.msg(" No sequence prefix supplied (See Parameters - Group prefix)");
179185
else plog.msg(" Load sequences with '" + prefix + "' prefix (See Parameters - Group prefix)");
@@ -193,13 +199,19 @@ private boolean loadSeqFiles() {
193199
plog.msg("Reading " + f.getName());
194200

195201
StringBuffer curSeq = new StringBuffer();
196-
String grpName = null, grpFullName = null, firstTok=null, line;
202+
String grpName = null, grpFullName = null, grpLabName = null, line;
197203

198204
BufferedReader fh = Utils.openGZIP(f.getAbsolutePath());
199-
205+
200206
while ((line = fh.readLine()) != null) {
201207

202-
if (line.startsWith("#") || line.isEmpty()) continue;
208+
if (line.startsWith("#") || line.isEmpty()) {
209+
if (line.contains("Written by SyMAP")) {
210+
if (line.contains("ConvertNCBI")) fileType=iNCBI;
211+
else if (line.contains("ConvertEnsembl")) fileType=iEns;
212+
}
213+
continue;
214+
}
203215

204216
if (line.startsWith(">")) {
205217
if (grpName != null && curSeq.length() >= minSize) {
@@ -215,36 +227,36 @@ private boolean loadSeqFiles() {
215227
String chrSeq = curSeq.toString(); // prevent two copies in memory at once
216228
curSeq.setLength(0);
217229

218-
uploadSequence(grpName,grpFullName,chrSeq,f.getName(),totalnSeqs+1);
230+
uploadSequence(grpName,grpFullName, grpLabName, chrSeq,f.getName(),totalnSeqs+1);
219231

220232
chrSeq = null;
221233
System.gc();
222234
}
223235
else {
224-
plog.msgToFile("+++ Dup seqid: " + grpName + " (" + firstTok + ") skipping...");
236+
plog.msgToFile("+++ Dup seqid: " + grpName + " skipping...");
225237
}
226238
} else seqIgnore++;
227239

228240
readSeq++;
229241
if (readSeq%100 == 0) Globals.rprt("Read sequences " + readSeq);
230242

231-
grpName = null; firstTok = grpFullName = "";
243+
grpName = null; grpFullName = "";
232244
curSeq.setLength(0);
233245

234-
if (!parseHasPrefix(line, prefix)){
246+
grpName = parse1stId(line, prefix);
247+
if (grpName == null){
235248
seqPrefixIgnore++;
236-
if (seqPrefixIgnore<=3) plog.msgToFile("+++ Invalid prefix, ignore: " + line);
237-
if (seqPrefixIgnore==3) plog.msgToFile("+++ Surpressing further invalid prefix ");
249+
if (seqPrefixIgnore<=maxPrtErr) plog.msgToFile("+++ Invalid prefix, ignore: " + line);
250+
if (seqPrefixIgnore==maxPrtErr) plog.msgToFile("+++ Surpressing further invalid prefix ");
238251
continue;
239252
}
240253

241-
grpName = Utils.parseGrpName(line,prefix);
242-
grpFullName = Utils.parseGrpFullName(line);
254+
grpFullName = parse1stId(line, "");
255+
grpLabName = parse2ndName(line, grpFullName);
256+
243257
if (grpName==null || grpFullName==null || grpName.equals("") || grpFullName.equals("")){
244258
return rtError("Unable to parse group name from:" + line);
245259
}
246-
String [] tl = line.split(" ");
247-
firstTok = (tl.length>0) ? tl[0] : Utils.parseGrpFullName(line);
248260
}
249261
else if (grpName!=null) { // sequence for valid grpName
250262
line = line.replaceAll("\\s+","");
@@ -271,7 +283,7 @@ else if (grpName!=null) { // sequence for valid grpName
271283

272284
String chrSeq = curSeq.toString();
273285
curSeq.setLength(0);
274-
uploadSequence(grpName, grpFullName, chrSeq, f.getName(), totalnSeqs+1);
286+
uploadSequence(grpName, grpFullName, grpLabName, chrSeq, f.getName(), totalnSeqs+1);
275287
chrSeq="";
276288
}
277289
else if (curSeq.length()>0) seqIgnore++;
@@ -301,24 +313,97 @@ else if (grpName!=null) { // sequence for valid grpName
301313
return false;
302314
}
303315
}
304-
private boolean parseHasPrefix(String name, String prefix){
305-
if (prefix.equals("")) return true;
306316

307-
String regx = "\\s*(" + prefix + ")(\\w+)\\s?.*";
308-
Pattern pat = Pattern.compile(regx,Pattern.CASE_INSENSITIVE);
317+
// Prefix - if no prefix, return null
318+
// Prefix - remove and return what is after it
319+
// No prefix - return 1st word after >
320+
private String parse1stId(String lineIn, String prefix) {
321+
String line = lineIn;
322+
if (line.startsWith(">")) line = line.substring(1, line.length());
323+
324+
line = line.trim();
325+
if (line.isBlank()) return null;
309326

310-
String n = name + " "; // hack, otherwise we need two cases in the regex
311-
if (n.startsWith(">")) n = n.substring(1);
312-
Matcher m = pat.matcher(n);
313-
if (m.matches()) return true;
314-
return false;
327+
if (prefix!=null && !prefix.isBlank()) {
328+
if (line.toLowerCase().startsWith(prefix.toLowerCase())) {
329+
line = line.substring(prefix.length(), line.length());
330+
}
331+
else return null;
332+
333+
}
334+
String id = line.split("\\s+")[0];
335+
if (id.length()>maxLenName) {
336+
plog.msgToFile("+++ Invalid Sequence Id; must be <= " + maxLenName + " characters, ignore: " + line);
337+
return null;
338+
}
339+
340+
String regex = "^[a-zA-Z0-9-_.]*$";
341+
Pattern pat = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
342+
Matcher m = pat.matcher(id);
343+
if (m.matches()) return id;
344+
return null;
345+
}
346+
// CAS582 find secondary name (labname)
347+
// >Chr1 NC0000.1 chromosome; xToSymap produces headers with 3 words
348+
// if not 3 words, check for NCBI header
349+
private String parse2ndName(String line, String mainId) {
350+
String [] words = line.split("\\s+");
351+
int len = words.length;
352+
353+
if (len>1 && len<4 && words[1].length()<=maxLenName) {
354+
if (fileType==iEns && mainId.endsWith(words[1])) return "";
355+
356+
if (words[1].equals(mainId)) return "";
357+
358+
return words[1];
359+
}
360+
361+
// NCBI Only Make the name the chromosome number
362+
// >BK006935.2 TPA_inf: Saccharomyces cerevisiae S288C chromosome I, complete sequence
363+
for (int i=0; i<words.length; i++) {
364+
String prefix=null;
365+
if (words[i].equalsIgnoreCase("chromosome")) prefix = "Chr";
366+
else if (words[i].equalsIgnoreCase("scaffold")) prefix = "Scaf";
367+
else if (words[i].equalsIgnoreCase("contig")) prefix = "Ctg";
368+
else if (words[i].equalsIgnoreCase("linkage")) prefix = "Lg";
369+
370+
if (prefix!=null) {
371+
if (i+1 < words.length && words[i+1].length()<=maxLenName) {
372+
String n = words[i+1];
373+
if (n.contains(",")) n = n.replace(",", "");
374+
375+
try {
376+
int d = Integer.parseInt(n);
377+
if (d<10) return String.format("%s%02d", prefix, d);
378+
else return prefix + n;
379+
}
380+
catch (Exception e) {}
381+
382+
if (n.matches("^[XYIV]*$")) return prefix + n;
383+
384+
if (n.matches("^[a-zA-Z0-9-_.]*$")) return n;
385+
}
386+
return prefix;
387+
}
388+
else {
389+
String w = words[i];
390+
if (w.contains(",")) w = w.replace(",", "");
391+
if (w.equalsIgnoreCase("mitochondrion") || w.equalsIgnoreCase("mitochondrial")) return "Mt";
392+
if (w.equalsIgnoreCase("chloroplast")) return "Cp";
393+
if (w.equals("plastid")) return "Pt";
394+
}
395+
}
396+
return "";
315397
}
398+
316399
/***********************************************************************/
317-
private void uploadSequence(String grp, String fullname, String seq, String file, int order) {
400+
private void uploadSequence(String grpname, String fullname, String labname, String seq, String file, int order) {
318401
try {
319402
// First, create the group; FIXME check for duplicates
320-
tdbc2.executeUpdate("INSERT INTO xgroups VALUES('0','" + projIdx + "','" +
321-
grp + "','" + fullname + "'," + order + ",'0')" );
403+
tdbc2.executeUpdate("INSERT INTO xgroups VALUES('0','" +
404+
projIdx + "','" + grpname + "','" + fullname + "','" +
405+
labname + "'," + order + ",'0')" ); // CAS582 add labname
406+
322407
String sql = "select max(idx) as maxidx from xgroups where proj_idx=" + projIdx;
323408
ResultSet rs = tdbc2.executeQuery(sql);
324409
rs.next();
@@ -347,7 +432,7 @@ private void uploadSequence(String grp, String fullname, String seq, String file
347432
}
348433
}
349434
catch (Exception e) {
350-
ErrorReport.print(e, "Fail load sequence: " + projIdx + "','" + grp + "','" + fullname + "'," + order);
435+
ErrorReport.print(e, "Fail load sequence: " + projIdx + "','" + grpname + "','" + fullname + "'," + order);
351436
Globals.prt(" This can happen if a project was just removed and another added immediately.");
352437
}
353438
}

0 commit comments

Comments
 (0)