# Insert data into a file at specific position

I have searched all over and can't figure out how to export data into an existing preformated file (quantum espresso input file) at a specific position.

Here is what I am trying to achieve. If the preformated file has the following structure:

&control
....
/

&system
.....
/

...

ATOMIC_POSITIONS
Si    0.0    0.0    0.0
Si    0.5    0.5    0.5

K_POINTS {automatic}
5 5 5 0 0 0


Now, I have written a small program to generate the atomic positions for a series of input files I need to create to run some QE jobs. The problema is that I have to export them first into separate files in the format shown under the ATOMIC_POSITIONS section. Then I have to go copy paste them in each input file. I can post the way I am generating the positions but it is quite trivial.

My questions is: is it possible to generate the positions and then insert them under the ATOMIC_POSITIONS line directly from Mathematica?

For smaller structures with small number of atoms, I can do this from bash, although is not very nice since I have to use bc and is quite cumbersome. For larger number of atoms, becomes very laborious and I am hoping there is a Mathematica solution.

Thanks

Edit: I did some digging and I think the answer lies within string operations. However, I can't figure out how to import everything as a string and then work with lines. It would be easy if I could tell mathematica to replace all lines below the ATOMIC_POSITIONS and above K_POINTS. Within the preformatted file there is a variable that sets the number of atoms which can be used to obtain the number of lines to be replaced. I'll keep digging!

• You could try to import the file as list of strings, look for "ATOMIC_POSITIONS", insert your lists of positions after that point and export again – Lukas Lang Sep 20 '17 at 8:53
• How do you do that? Can you explain it a bit more please? – lucian Sep 20 '17 at 9:42
• I think that you could solve this with sqllite which can be managed by mathematica – elbOlita Sep 20 '17 at 9:42
• i have never worked with sqlite unfortunately, but I would be willing to give it a try if you could give me some pointers! cheers – lucian Sep 20 '17 at 9:56
• Perhaps ImportString and StringReplace and/or StringReplacePart might be of use to you – user42582 Sep 20 '17 at 10:41

While it would not be difficult to do this explicitly with importing the content and some string-replacing, it seems to be a nice use case for the templating system. The following should do what I think you need:

template = FileNameJoin[{\$HomeDirectory, "Desktop", "qeinput.tmp"}]
outputfile = StringReplace[template, ".tmp" -> ".inp"]
atomicpositions = {{"Si", 0.0, 0.0}, {"Si", 0.5, 0.5}};
FileTemplateApply[
FileTemplate[template],
<|"AtomicPositions" -> ExportString[atomicpositions, "Table"]|>,
outputfile
]


to check the result you could do:

FilePrint[outputfile]


Some notes:

• the content of the template would contain a string AtomicPositions where you want those to be inserted:

...
ATOMIC_POSITIONS
AtomicPositions

K_POINTS {automatic}
...

• if the backquotes would cause problems for your specific file format, you probably would need to resort to lower level functionality ( Import, StringReplace and Export) with which you can use markers for the template slots that are OK for your file format.

• if the program to read the file is picky about exact positions/alignments in the ATOMIC_POSITIONS section, you would need some extra effort to format the table exactly how the program expects it instead of the simple ExportString[atomicpositions,"Table"].

• I will give this a try. However there are some issues: why do you need to insert the extra line AtomicPositions ? this program that I am creating the input file for is very picky with regard to what the file contains! To give you an idea, if the file is created in windows and there is the wrong end of line, the program will not work! So anything that it does not recognize will trigger an error. – lucian Sep 21 '17 at 10:12
• That line is just a marker that will be replaced with the actual content (a very standard approach for all kinds of templating engines). The final output will not contain the  AtomicPositions  anymore but instead the lines generated by ExportString. So the program reading the file will never see that line, and I don't think that it will cause any problems. Have you looked at the output file and tried whether that can be read by the program? – Albert Retey Sep 21 '17 at 10:30
• This is sweet! Thank you! At the moment I am in the middle of something but I got to read the documentation on templates a bit and I think this is what I need! I can create a template with markers in the places I need and then replace them accordingly! I will accept this answer after I will get it working in a few days. But I think this is the best solution yet! – lucian Sep 21 '17 at 10:39