Skip to content

Commit d47f06f

Browse files
committed
File.comp from Greg Tucker -> McXtrace
1 parent df352c2 commit d47f06f

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*******************************************************************************
2+
*
3+
* McXtrace, x-ray tracing package
4+
* Copyright, All rights reserved
5+
* DTU Physics, Kgs. Lyngby, Denmark
6+
* Synchrotron SOLEIL, Saint-Aubin, France
7+
*
8+
* Instrument: test_File
9+
*
10+
* %Identification
11+
* Written by: Greg Tucker
12+
* Date: 2024
13+
* Origin: ESS
14+
* %INSTRUMENT_SITE: Tests_other
15+
*
16+
* Demonstrates how to use the File.comp component for storing instrument
17+
* input-files as METADATA blocks
18+
*
19+
* %Description
20+
* Demonstrates how to use the File.comp component for storing instrument
21+
* input-files as METADATA blocks
22+
*
23+
* %Link
24+
* From https://github.com/g5t/mccode-file
25+
*
26+
* %End
27+
*******************************************************************************/
28+
DEFINE INSTRUMENT test_File()
29+
TRACE
30+
COMPONENT Origin = Progress_bar() AT (0, 0, 0) ABSOLUTE
31+
METADATA "mimetype/text" origin_info %{
32+
# Generated file
33+
Here is some data to go into a file.
34+
%}
35+
36+
COMPONENT source = Source_flat(E0=40, dE=0.01, focus_xw=0.0001, focus_yh=0.0001, radius=0.0001, dist=1
37+
) AT (0, 0, 0) RELATIVE Origin
38+
39+
COMPONENT first_file = File(filename="first.txt", metadatakey="stored", keep=1) AT (0, 0, 0) ABSOLUTE
40+
METADATA txt stored %{
41+
Store text to write in first.txt
42+
%}
43+
44+
COMPONENT second_file = File(filename="second.txt", metadatakey="Origin:origin_info", keep=1)
45+
AT (0, 0, 0) ABSOLUTE
46+
47+
END
48+

mcxtrace-comps/misc/File.comp

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*******************************************************************************
2+
*
3+
* McXtrace, x-ray tracing package
4+
* Copyright, All rights reserved
5+
* DTU Physics, Kgs. Lyngby, Denmark
6+
* Synchrotron SOLEIL, Saint-Aubin, France
7+
*
8+
* Component: File
9+
*
10+
* %I
11+
*
12+
* Written by: Greg Tucker
13+
* Date: 2024
14+
* Origin: ESS
15+
*
16+
* File.comp - allows to generate instrument/component input-files
17+
* from METADATA blocks
18+
*
19+
* %D
20+
* File.comp - allows to generate instrument/component input-files
21+
* from METADATA blocks - see test_File.instr for an example.
22+
*
23+
* %P
24+
* Input parameters:
25+
* filename: [string] Filename for output-file generated from metadata block
26+
* metadatakey: [string] METADATA-key for looking up file content (may belong to File instance or another comp)
27+
* keep: [1] Flag to indicate if file should be kept post-simulation
28+
*
29+
* %E
30+
*******************************************************************************/
31+
DEFINE COMPONENT File
32+
SETTING PARAMETERS (string filename=0, string metadatakey, int keep=0)
33+
OUTPUT PARAMETERS ()
34+
SHARE
35+
%{
36+
%}
37+
DECLARE
38+
%{
39+
char * key;
40+
char * name;
41+
%}
42+
INITIALIZE
43+
%{
44+
// Sort-out the key that we are searching for
45+
if (metadatakey == NULL || metadatakey[0] == '\0'){
46+
key = malloc((strlen(NAME_CURRENT_COMP) + 1) * sizeof(char));
47+
strcpy(key, NAME_CURRENT_COMP);
48+
} else {
49+
key = malloc((strlen(metadatakey) + 1) * sizeof(char));
50+
strcpy(key, metadatakey);
51+
}
52+
int matches = metadata_table_defined(num_metadata, metadata_table, key);
53+
if (matches != 1) {
54+
// 0 would mean _no_ matches; maybe they metadata name without the component was given?
55+
if (matches == 0 && strcmp(key, NAME_CURRENT_COMP)) {
56+
free(key);
57+
key = malloc((strlen(NAME_CURRENT_COMP) + strlen(metadatakey) + 2) * sizeof(char));
58+
sprintf(key, "%s:%s", NAME_CURRENT_COMP, metadatakey);
59+
matches = metadata_table_defined(num_metadata, metadata_table, key);
60+
}
61+
// there's a bug in metadata_table_defined that returns num_metadata if key == NULL
62+
// But since key _isn't_ null, any other result _should_ mean key == A_COMPONENT_NAME
63+
// _and_ that component defines _multiple_ METADATA entries.
64+
else {
65+
printf("%s: There are %d METADATA entries that match %s; please select only one of:\n", NAME_CURRENT_COMP, matches, key);
66+
metadata_table_print_component_keys(num_metadata, metadata_table, key);
67+
exit(1);
68+
}
69+
}
70+
if (metadata_table_defined(num_metadata, metadata_table, key) != 1) {
71+
fprintf(stderr, "%s: No unique metadata defined with key %s\n", NAME_CURRENT_COMP, key);
72+
exit(1);
73+
}
74+
75+
char * name_part = metadata_table_key_literal(key);
76+
if (name_part == NULL) {
77+
#if defined(__MCCODE_VERSION__) && __MCCODE_VERSION__ >= 305000L
78+
// We already restrict that only one key matches.
79+
name_part = metadata_table_name(num_metadata, metadata_table, key);
80+
// is key NAME_CURRENT_COMP or something provided by the user? We don't know
81+
// so we _must_ cycle the key allocation to make this work.
82+
char * new_key = malloc((strlen(key) + strlen(name_part) + 2) * sizeof(char));
83+
sprintf(new_key, "%s:%s", key, name_part);
84+
free(key);
85+
key = new_key;
86+
#else
87+
printf("Can not update the key automatically prior to McCode v3.5.0, please fix %s usage or upgrade\n", NAME_CURRENT_COMP);
88+
exit(1);
89+
#endif
90+
}
91+
92+
if (filename == NULL || filename[0] == '\0'){
93+
char * comp_part = metadata_table_key_component(key);
94+
name = malloc((strlen(comp_part) + strlen(name_part) + 2) * sizeof(char));
95+
sprintf(name, "%s_%s", comp_part, name_part);
96+
free(comp_part);
97+
} else{
98+
name = malloc((strlen(filename) + 1) * sizeof(char));
99+
strcpy(name, filename);
100+
}
101+
102+
free(name_part);
103+
104+
// Read the file contents and write them to file now.
105+
FILE * file_ptr = fopen(name, "w");
106+
fprintf(file_ptr, "%s", metadata_table_literal(num_metadata, metadata_table, key));
107+
fclose(file_ptr);
108+
%}
109+
TRACE
110+
%{
111+
// Do nothing
112+
%}
113+
FINALLY
114+
%{
115+
// (Optionally) Remove the file now that the runtime is done
116+
if (!keep && !remove(name)) {
117+
fprintf(stderr, "%s: Could not remove file %s\n", NAME_CURRENT_COMP, name);
118+
}
119+
if (key) free(key);
120+
if (name) free(name);
121+
%}
122+
MCDISPLAY
123+
%{
124+
%}
125+
END

0 commit comments

Comments
 (0)