@@ -33,7 +33,7 @@ struct ImportSources
33
33
ic_dc:: ImportSource
34
34
end
35
35
36
- function ImportSources (src:: Dict )
36
+ function ImportSources (src:: Dict , path_to_project :: AbstractString )
37
37
required = true
38
38
config = ImportSource (src, " config" , " config" , " PhysiCell_settings.xml" , " file" , required)
39
39
main = ImportSource (src, " main" , " " , " main.cpp" , " file" , required; input_folder_key = :custom_code )
@@ -42,14 +42,82 @@ function ImportSources(src::Dict)
42
42
43
43
required = false
44
44
rules = ImportSource (src, " rules" , " config" , " cell_rules.csv" , " file" , required; pcvct_name= " base_rulesets.csv" )
45
- intracellular = ImportSource (src, " intracellular " , " config" , " intracellular.xml " , " file " , required )
45
+ intracellular = prepareIntracellularImport (src, config, path_to_project )
46
46
ic_cell = ImportSource (src, " ic_cell" , " config" , " cells.csv" , " file" , required)
47
47
ic_substrate = ImportSource (src, " ic_substrate" , " config" , " substrates.csv" , " file" , required)
48
48
ic_ecm = ImportSource (src, " ic_ecm" , " config" , " ecm.csv" , " file" , required)
49
49
ic_dc = ImportSource (src, " ic_dc" , " config" , " dcs.csv" , " file" , required)
50
50
return ImportSources (config, main, makefile, custom_modules, rules, intracellular, ic_cell, ic_substrate, ic_ecm, ic_dc)
51
51
end
52
52
53
+ function prepareIntracellularImport (src:: Dict , config:: ImportSource , path_to_project:: AbstractString )
54
+ if haskey (src, " intracellular" ) || isfile (joinpath (path_to_project, " config" , " intracellular.xml" ))
55
+ return ImportSource (src, " intracellular" , " config" , " intracellular.xml" , " file" , true )
56
+ end
57
+ # ! now attempt to read the config file and assemble the intracellular file
58
+ path_to_xml = joinpath (path_to_project, config. path_from_project)
59
+ if ! isfile (path_to_xml) # ! if the config file is not found, then we cannot proceed with grabbing the intracellular data, just return the default
60
+ return ImportSource (src, " intracellular" , " config" , " intracellular.xml" , " file" , false )
61
+ end
62
+ xml_doc = openXML (path_to_xml)
63
+ cell_definitions_element = retrieveElement (xml_doc, [" cell_definitions" ])
64
+ cell_type_to_components_dict = Dict {String,PhysiCellComponent} ()
65
+ for cell_definition_element in child_elements (cell_definitions_element)
66
+ if name (cell_definition_element) != " cell_definition"
67
+ continue
68
+ end
69
+ cell_type = attribute (cell_definition_element, " name" )
70
+ phenotype_element = find_element (cell_definition_element, " phenotype" )
71
+ intracellular_element = find_element (phenotype_element, " intracellular" )
72
+ if isnothing (intracellular_element)
73
+ continue
74
+ end
75
+ type = attribute (intracellular_element, " type" )
76
+ if type ∉ [" roadrunner" , " dfba" ]
77
+ throw (ErrorException (" pcvct does not yet support intracellular type $type ." ))
78
+ end
79
+ path_to_file = find_element (intracellular_element, " sbml_filename" ) |> content
80
+ temp_component = PhysiCellComponent (type, basename (path_to_file))
81
+ # ! now we have to rely on the path to the file is correct relative to the parent directory of the config file (that should usually be the case)
82
+ path_to_src = joinpath (path_to_project, path_to_file)
83
+ path_to_dest = _create_component_dest_file_name (readlines (path_to_src), temp_component)
84
+ component = PhysiCellComponent (type, basename (path_to_dest))
85
+ if ! isfile (path_to_dest)
86
+ cp (path_to_src, path_to_dest)
87
+ end
88
+
89
+ cell_type_to_components_dict[cell_type] = component
90
+ end
91
+
92
+ if isempty (cell_type_to_components_dict)
93
+ return ImportSource (src, " intracellular" , " config" , " intracellular.xml" , " file" , false )
94
+ end
95
+
96
+ intracellular_folder = assembleIntracellular! (cell_type_to_components_dict; name= " temp_assembled_from_$(splitpath (path_to_project)[end ]) " , skip_db_insert= true )
97
+ mv (joinpath (locationPath (:intracellular , intracellular_folder), " intracellular.xml" ), joinpath (path_to_project, " config" , " assembled_intracellular_for_import.xml" ); force= true )
98
+ rm (locationPath (:intracellular , intracellular_folder); force= true , recursive= true )
99
+
100
+ closeXML (xml_doc)
101
+ return ImportSource (src, " intracellular" , " config" , " assembled_intracellular_for_import.xml" , " file" , true ; pcvct_name= " intracellular.xml" )
102
+ end
103
+
104
+ function _create_component_dest_file_name (src_lines:: Vector{String} , component:: PhysiCellComponent )
105
+ base_path = joinpath (data_dir, " components" , component. path_from_components)
106
+ folder = dirname (base_path)
107
+ mkpath (folder)
108
+ base_filename, file_ext = basename (base_path) |> splitext
109
+ n = 0
110
+ path_to_dest = joinpath (folder, base_filename * file_ext)
111
+ while isfile (path_to_dest)
112
+ if src_lines == readlines (path_to_dest)
113
+ return path_to_dest
114
+ end
115
+ n += 1
116
+ path_to_dest = joinpath (folder, base_filename * " _$(n) " * file_ext)
117
+ end
118
+ return path_to_dest
119
+ end
120
+
53
121
mutable struct ImportDestFolder
54
122
path_from_inputs:: AbstractString
55
123
created:: Bool
@@ -79,7 +147,7 @@ function ImportDestFolders(path_to_project::AbstractString, dest::Dict)
79
147
80
148
# ! optional folders
81
149
rules = ImportDestFolder (path_fn (" rules" , " rulesets_collections" ), created, description)
82
- intracellular = ImportDestFolder (path_fn (" intracellular" , " intracellular " ), created, description)
150
+ intracellular = ImportDestFolder (path_fn (" intracellular" , " intracellulars " ), created, description)
83
151
ic_cell = ImportDestFolder (path_fn (" ic_cell" , joinpath (" ics" , " cells" )), created, description)
84
152
ic_substrate = ImportDestFolder (path_fn (" ic_substrate" , joinpath (" ics" , " substrates" )), created, description)
85
153
ic_ecm = ImportDestFolder (path_fn (" ic_ecm" , joinpath (" ics" , " ecms" )), created, description)
@@ -101,7 +169,7 @@ The following keys are recognized: $(join(["`$fn`" for fn in fieldnames(ImportDe
101
169
- `extreme_caution::Bool`: If true, will ask for confirmation before deleting any folders created during the import process. Care has been taken to ensure this is unnecessary. Provided for users who want to be extra cautious.
102
170
"""
103
171
function importProject (path_to_project:: AbstractString , src= Dict (), dest= Dict (); extreme_caution:: Bool = false )
104
- project_sources = ImportSources (src)
172
+ project_sources = ImportSources (src, path_to_project )
105
173
import_dest_folders = ImportDestFolders (path_to_project, dest)
106
174
success = resolveProjectSources! (project_sources, path_to_project)
107
175
if success
@@ -299,9 +367,6 @@ function adaptMain(path_from_inputs::AbstractString)
299
367
return true
300
368
end
301
369
302
- idx = findfirst (x-> contains (x, " <fstream>" ), lines)
303
- insert! (lines, idx+ 1 , " #include <getopt.h>" )
304
-
305
370
idx1 = findfirst (x-> contains (x, " // load and parse settings file(s)" ), lines)
306
371
if isnothing (idx1)
307
372
idx1 = findfirst (x-> contains (x, " bool XML_status = false;" ), lines)
@@ -314,19 +379,27 @@ function adaptMain(path_from_inputs::AbstractString)
314
379
return false
315
380
end
316
381
end
317
- idx2 = findfirst (x -> contains (x, " // copy config file to" ), lines)
318
- if isnothing (idx2)
319
- idx2 = findfirst (x -> contains (x, " system(" ) && contains (x, " copy_command" ), lines)
320
- if isnothing (idx2)
321
- msg = """
322
- Could not identify where the copy command is in the main.cpp file.
323
- Aborting the export process.
324
- """
325
- println (msg)
326
- return false
327
- end
328
- end
329
- deleteat! (lines, idx1: (idx2- 1 ))
382
+ idx_not_xml_status = findfirst (x-> contains (x, " !XML_status" ), lines)
383
+ idx2 = idx_not_xml_status + findfirst (x -> contains (x, " }" ), lines[idx_not_xml_status: end ]) - 1
384
+ # idx2 = findfirst(x -> contains(x, "// copy config file to"), lines)
385
+ # if isnothing(idx2)
386
+ # idx2 = findfirst(x -> contains(x, "system(") && contains(x, "copy_command"), lines)
387
+ # if isnothing(idx2)
388
+ # idx2 = findfirst(x -> contains(x, "// OpenMP setup"), lines)
389
+ # if isnothing(idx2)
390
+ # idx2 = findfirst(x -> contains(x, "omp_set_num_threads("), lines)
391
+ # if isnothing(idx2)
392
+ # msg = """
393
+ # Could not identify where the copy command is in the main.cpp file.
394
+ # Aborting the export process.
395
+ # """
396
+ # println(msg)
397
+ # return false
398
+ # end
399
+ # end
400
+ # end
401
+ # end
402
+ deleteat! (lines, idx1: idx2)
330
403
331
404
parsing_block = """
332
405
// read arguments
0 commit comments