33import cbit .util .xml .VCLogger ;
44import cbit .util .xml .VCLoggerException ;
55import cbit .vcell .biomodel .BioModel ;
6+ import cbit .vcell .client .server .DynamicClientProperties ;
7+ import cbit .vcell .resource .PropertyLoader ;
8+ import cbit .vcell .resource .ResourceUtil ;
9+ import cbit .vcell .xml .ExternalDocInfo ;
10+ import cbit .vcell .xml .XMLSource ;
11+ import cbit .vcell .xml .XMLTags ;
12+ import cbit .vcell .xml .XmlHelper ;
613import org .jdom2 .Document ;
714import org .jdom2 .Element ;
15+ import org .jdom2 .Namespace ;
16+ import org .jdom2 .input .SAXBuilder ;
817import org .jdom2 .output .Format ;
918import org .jdom2 .output .XMLOutputter ;
10- import org .junit .jupiter .api .AfterAll ;
11- import org .junit .jupiter .api .Assertions ;
12- import org .junit .jupiter .api .BeforeAll ;
13- import org .junit .jupiter .api .Tag ;
19+ import org .junit .jupiter .api .*;
1420import org .junit .jupiter .params .ParameterizedTest ;
1521import org .junit .jupiter .params .provider .MethodSource ;
1622import org .sbml .jsbml .SBMLDocument ;
1723import org .sbml .jsbml .SBMLReader ;
1824import org .vcell .sbml .vcell .SBMLImporter ;
25+ import org .vcell .util .UnzipUtility ;
1926
2027import java .io .*;
28+ import java .net .URL ;
29+ import java .nio .charset .StandardCharsets ;
2130import java .nio .file .Files ;
31+ import java .nio .file .Path ;
32+ import java .nio .file .Paths ;
33+ import java .nio .file .StandardOpenOption ;
2234import java .util .*;
2335import java .util .stream .Collectors ;
36+ import java .util .HashMap ;
37+ import java .util .Map ;
2438
2539import static org .junit .jupiter .api .Assertions .fail ;
2640
@@ -112,6 +126,8 @@ public static Map<Integer, SBMLTestSuiteTest.FAULT> knownFaults() {
112126 faults .put (340 , SBMLTestSuiteTest .FAULT .MATHML_PARSING ); // cause: UnsupportedConstruct: error parsing expression ' <math><apply><gt/><piecewise><piece><apply><minus/><csymbol encoding="text" definitionURL="http://www.sbml.org/sbml/symbols/time">
113127 faults .put (342 , SBMLTestSuiteTest .FAULT .EXPRESSION_BINDING_EXCEPTION ); // cause: Error binding global parameter 'TGF_beta_dose_mol_per_cell' to model: 'UNRESOLVED.initConc' is either not found in your model or is not allowed to be used in the current context.
114128 faults .put (353 , SBMLTestSuiteTest .FAULT .NONINTEGER_STOICH ); // cause: UnsupportedConstruct: Non-integer stoichiometry ('12345.7' for reactant 'cpd_C00369Glc_CS' in reaction 'rn_R02112CS_G2') or stoichiometryMath not handled in VCell at this time.
129+ faults .put (354 , SBMLTestSuiteTest .FAULT .COMPARTMENT_CONSTANT_FALSE ); // cause: Error adding Feature to vcModel CompartmentError: compartment 'cytosol' has constant attribute set to False, not currently supported.
130+ faults .put (355 , SBMLTestSuiteTest .FAULT .COMPARTMENT_CONSTANT_FALSE ); // cause: Error adding Feature to vcModel CompartmentError: compartment 'cytosol' has constant attribute set to False, not currently supported.
115131 faults .put (383 , SBMLTestSuiteTest .FAULT .NONINTEGER_STOICH ); // cause: UnsupportedConstruct: Non-integer stoichiometry ('1.5' for product 'PGA' in reaction 'PGA_prod_Vo') or stoichiometryMath not handled in VCell at this time.
116132 faults .put (384 , SBMLTestSuiteTest .FAULT .NONINTEGER_STOICH ); // cause: UnsupportedConstruct: Non-integer stoichiometry ('1.5' for product 'PGA' in reaction 'PGA_prod_Vo') or stoichiometryMath not handled in VCell at this time.
117133 faults .put (385 , SBMLTestSuiteTest .FAULT .NONINTEGER_STOICH ); // cause: UnsupportedConstruct: Non-integer stoichiometry ('1.5' for product 'PGA' in reaction 'PGA_prod_Vo') or stoichiometryMath not handled in VCell at this time.
@@ -258,6 +274,8 @@ public void testSbmlTestSuiteImport(Integer biomodelsDbModelNumber) throws Excep
258274 fault = SBMLTestSuiteTest .FAULT .MATHML_PARSING ;
259275 }else if (cause .contains ("class org.sbml.jsbml.Constraint cannot be cast to class org.sbml.jsbml.SBMLDocument" )) {
260276 fault = SBMLTestSuiteTest .FAULT .CONSTRAINT_CLASS_CAST_EXCEPTION ;
277+ }else if (cause .contains ("CompartmentError: compartment" ) && cause .contains ("constant attribute set to False" )) {
278+ fault = SBMLTestSuiteTest .FAULT .COMPARTMENT_CONSTANT_FALSE ;
261279 }
262280
263281 try (BufferedWriter codeProblemFileWriter = new BufferedWriter (new FileWriter (codeKnownProblemFile , true ));
@@ -279,7 +297,236 @@ public void testSbmlTestSuiteImport(Integer biomodelsDbModelNumber) throws Excep
279297 }
280298 }
281299
282- public static void main (String [] args ) {
300+ /*
301+ * goes through the list of BMDB models (bioModelsNetInfo.xml)
302+ * downloads from the website (www.ebi.ac.uk) all those marked as supported
303+ * tries to import them in vcell
304+ * creates a list with those that fail
305+ *
306+ * for simplicity, place the bioModelsNetInfo.xml file in a convenient location and edit bioModelsNetInfoFile accordingly
307+ * this is not really a test and takes quite a long time to run, keep it commented out unless needed
308+ */
309+ // @Test
310+ // public void importAllBmdbTest() {
311+ // try {
312+ // File bioModelsNetInfoFile = new File("C:/dan/projects/git/vcell/vcell-client/src/main/resources/bioModelsNetInfo.xml");
313+ // Map<String, BioModelData> modelInfoMap = parseXmlFile(bioModelsNetInfoFile);
314+ //// modelInfoMap.forEach((id, data) -> System.out.println("ID: " + id + " -> " + data));
315+ //
316+ // Set<Integer> failuresSet = new LinkedHashSet<> ();
317+ // for (Map.Entry<String, BioModelData> entry : modelInfoMap.entrySet()) {
318+ //
319+ // String id = entry.getKey();
320+ // String name = entry.getValue().name;
321+ // boolean supported = entry.getValue().supported;
322+ // if(supported == false) {
323+ //// System.out.println("Skipping: " + id + ", unsupported");
324+ // continue;
325+ // }
326+ // if(slowModelSet().contains(idToIndex(id))) {
327+ //// System.out.println("Skipping: " + id + ", slow");
328+ // continue; // skip the slow ones
329+ // }
330+ //
331+ // System.out.println("Reading: " + id);
332+ // ExternalDocInfo externalDocInfo = download(name, id);
333+ //
334+ // XMLSource xmlSource = externalDocInfo.createXMLSource();
335+ // org.jdom2.Element rootElement = xmlSource.getXmlDoc().getRootElement();
336+ // String xmlType = rootElement.getName();
337+ //
338+ // if (!xmlType.equals(XMLTags.SbmlRootNodeTag)) {
339+ // throw new RuntimeException("Expected SBML document");
340+ // }
341+ // try {
342+ // VCLogger transLogger = null;
343+ // Namespace namespace = rootElement.getNamespace(XMLTags.SBML_SPATIAL_NS_PREFIX);
344+ // boolean isBMDB = externalDocInfo.isBioModelsNet();
345+ // boolean bIsSpatial = (namespace == null) ? false : true;
346+ // BioModel doc = XmlHelper.importSBML(transLogger, xmlSource, bIsSpatial);
347+ //
348+ // } catch(Exception e) {
349+ // failuresSet.add(idToIndex(id));
350+ // System.err.println(" ...found new failure");
351+ // }
352+ // System.out.println(" ...success");
353+ // }
354+ // String failures = convertSetToString(failuresSet);
355+ // System.out.println(failures);
356+ // } catch(Exception e) {
357+ // System.out.println(e.getMessage());
358+ // }
359+ // }
360+ /*
361+ * same as above, goes to all the models marked as fails and tries to import them, makes a list with those that actually
362+ * can be imported
363+ *
364+ * WARNING: our SBML parser is "eating" some errors, if exceptions are being fired the imported model is probably wrong
365+ * even though it gets imported
366+ */
367+ // @Test
368+ // public void checkExistingFailuresTest() {
369+ // try {
370+ // File bioModelsNetInfoFile = new File("C:/dan/projects/git/vcell/vcell-client/src/main/resources/bioModelsNetInfo.xml");
371+ // Map<String, BioModelData> modelInfoMap = parseXmlFile(bioModelsNetInfoFile);
372+ //
373+ // Set<Integer> failuresNowWorkingSet = new LinkedHashSet<> (); // models marked as failures, but now work
374+ // for (Map.Entry<String, BioModelData> entry : modelInfoMap.entrySet()) {
375+ //
376+ // String id = entry.getKey();
377+ // String name = entry.getValue().name;
378+ // boolean supported = entry.getValue().supported;
379+ // if(supported == true) {
380+ // System.out.println("Skipping: " + id + ", marked as supported");
381+ // continue;
382+ // }
383+ // if(slowModelSet().contains(idToIndex(id))) {
384+ // System.out.println("Skipping: " + id + ", slow");
385+ // continue; // skip the slow ones
386+ // }
387+ //
388+ // System.out.println("Reading: " + id);
389+ // ExternalDocInfo externalDocInfo = download(name, id);
390+ //
391+ // XMLSource xmlSource = externalDocInfo.createXMLSource();
392+ // org.jdom2.Element rootElement = xmlSource.getXmlDoc().getRootElement();
393+ // String xmlType = rootElement.getName();
394+ //
395+ // if (!xmlType.equals(XMLTags.SbmlRootNodeTag)) {
396+ // throw new RuntimeException("Expected SBML document");
397+ // }
398+ // try {
399+ // VCLogger transLogger = null;
400+ // Namespace namespace = rootElement.getNamespace(XMLTags.SBML_SPATIAL_NS_PREFIX);
401+ // boolean isBMDB = externalDocInfo.isBioModelsNet();
402+ // boolean bIsSpatial = (namespace == null) ? false : true;
403+ // BioModel doc = XmlHelper.importSBML(transLogger, xmlSource, bIsSpatial);
404+ // System.out.println(" ...success");
405+ // failuresNowWorkingSet.add(idToIndex(id));
406+ // } catch(Exception e) {
407+ // System.err.println(" ...still fails");
408+ // }
409+ // }
410+ // String failuresNowWorking = convertSetToString(failuresNowWorkingSet);
411+ // System.out.println(failuresNowWorking);
412+ // } catch(Exception e) {
413+ // System.out.println(e.getMessage());
414+ // }
415+ // }
416+
417+ private static final String IdPrefix = "BIOMD" ;
418+ public static String indexToId (int index ) { // ex: 47 -> BIOMD0000000047
419+ String paddedSuffix = String .format ("%010d" , index );
420+ return IdPrefix + paddedSuffix ;
421+ }
422+ public static int idToIndex (String id ) { // ex: BIOMD0000000123 -> 123
423+ String suffixStr = id .substring (IdPrefix .length ());
424+ return Integer .parseInt (suffixStr );
425+ }
426+ public static String convertSetToString (Set <Integer > numbers ) {
427+ String stringOfNumbers = numbers .stream ()
428+ .map (String ::valueOf ) // convert each integer to a string
429+ .collect (Collectors .joining ("," )); // join with commas
430+ return stringOfNumbers ;
431+ }
432+
433+ private ExternalDocInfo download (String name , String id ) throws Exception {
434+ String simDataDir = ResourceUtil .getLocalRootDir ().getAbsolutePath (); // C:\Users\myname\.vcell\simdata
435+ String tempDir = simDataDir + File .separator + "temp" ;
436+ String destDirectory = tempDir + File .separator + id ;
437+ String zipFilePath = destDirectory + ".zip" ;
438+
439+ Path tempDirPath = Paths .get (tempDir );
440+ Files .createDirectories (tempDirPath ); // temp may not be there, we make it
441+
442+ byte [] responseContent = null ;
443+ URL url = new URL ("https://www.ebi.ac.uk/biomodels/search/download?models=" + id );
444+ ByteArrayOutputStream baos = new ByteArrayOutputStream ();
445+ InputStream is = null ;
446+ try {
447+ try {
448+ is = url .openStream ();
449+ }catch (Exception e ) {
450+ e .printStackTrace ();
451+ if (is != null ) { is .close (); }
452+ //Try with http instead of https
453+ String newUrlString = url .toString ().replaceFirst ("^https" , "http" );
454+ url = new URL (newUrlString );
455+ is = url .openStream ();
456+ }
457+ byte [] byteChunk = new byte [4096 ]; // Or whatever size you want to read in at a time.
458+ int n ;
459+
460+ while ( (n = is .read (byteChunk )) > 0 ) {
461+ baos .write (byteChunk , 0 , n );
462+ }
463+ responseContent = baos .toByteArray ();
464+ }
465+ catch (IOException e ) {
466+ System .err .printf ("Failed while reading bytes from %s: %s" , url .toExternalForm (), e .getMessage ());
467+ // e.printStackTrace ();
468+ throw new RuntimeException ("Failed while reading bytes from: " + url .toExternalForm ());
469+ }
470+ finally {
471+ if (is != null ) { is .close (); }
472+ }
473+ if (responseContent == null ) {
474+ throw new RuntimeException ("Failed while reading bytes from: " + url .toExternalForm ());
475+ }
476+
477+ try {
478+ File file = new File (zipFilePath );
479+ Files .write (file .toPath (), responseContent , StandardOpenOption .CREATE , StandardOpenOption .WRITE , StandardOpenOption .TRUNCATE_EXISTING );
480+ UnzipUtility uu = new UnzipUtility ();
481+ uu .unzip (zipFilePath , destDirectory );
482+ } catch (IOException e ) {
483+ e .printStackTrace ();
484+ }
485+ String unzippedPath = destDirectory + File .separator + id + ".xml" ;
486+ String bioModelSBML = new String (Files .readAllBytes (Paths .get (unzippedPath )), StandardCharsets .UTF_8 );
487+ try {
488+ Files .deleteIfExists (Paths .get (zipFilePath )); // the original zip file
489+ Files .deleteIfExists (Paths .get (unzippedPath )); // the unzipped SBML file
490+ Files .deleteIfExists (Paths .get (destDirectory )); // its directory
491+ } catch (IOException e ) {
492+ e .printStackTrace ();
493+ }
494+ ExternalDocInfo externalDocInfo = ExternalDocInfo .createBioModelsNetExternalDocInfo (bioModelSBML , name );
495+ return externalDocInfo ;
496+ }
497+ public Map <String , BioModelData > parseXmlFile (File xmlFile ) throws Exception {
498+ Map <String , BioModelData > bioModelMap = new LinkedHashMap <>();
499+
500+ SAXBuilder builder = new SAXBuilder ();
501+ Document document = builder .build (xmlFile );
502+ Element rootElement = document .getRootElement ();
503+
504+ List <Element > bioModelInfos = rootElement .getChildren ("BioModelInfo" );
505+ for (Element bioModel : bioModelInfos ) {
506+ String id = bioModel .getAttributeValue ("ID" );
507+ boolean supported = Boolean .parseBoolean (bioModel .getAttributeValue ("Supported" ));
508+ String name = bioModel .getAttributeValue ("Name" );
509+ bioModelMap .put (id , new BioModelData (supported , name ));
510+ System .out .println ("ID: " + id + ", Supported: " + supported + ", Name: " + name );
511+ }
512+ return bioModelMap ;
513+ }
514+
515+ public class BioModelData implements Serializable {
516+ public final boolean supported ;
517+ public final String name ;
518+
519+ public BioModelData (boolean supported , String name ) {
520+ this .supported = supported ;
521+ this .name = name ;
522+ }
523+ @ Override
524+ public String toString () {
525+ return "BioModelData{name='" + name + "', supported=" + supported + "}" ;
526+ }
527+ }
528+
529+ public static void main (String [] args ) {
283530 try {
284531 if (args .length != 1 ){
285532 System .out .println ("usage: BMDB_SBMLImportTest xmlManifestFile" );
0 commit comments