lunedì 15 febbraio 2016

addiction to GNU pot

Since I do not have Origin (the scientific software, not the EA Steam-copy-paste) I tried to use alternatives like SciDavis or QtPlot. After struggling for hours to get what I needed, I went back to the roots using GNUPlot.

I hereby post a little script that I used to print the same function with different parameters. The function is a LogNormal distribution and I think that, for a fast visualization, my script is more then enough for everyone.
It's not that easy to find all the commands together in a single example and I don't want  to waste any more hours looking around.

Comments start with '#' character.



f(x,m,s,d)=1/((x-d)*s*sqrt(2*pi))*exp(-(log(x-d)-m)**2/(2*s*s))
#the function I want to plot with parameters m, s, d and variable x

set autoscale

set border 3 front 
set tics nomirror out scale 0.75
#these two lines remove the top and right borders, leaving only the 2 xy axes

set yrange [0:0.22]
set xrange [0:35]
#set the min-max range of the two axes x and yù

set ytics 0.025
set xtics 2
#set the spacing on axes, the tics

set ylabel "p(D)"
set xlabel "E.C.D. [nm]"
#sets the label to the axes

plot f(x, 2.38, 0.38, 0) notitle lt -1 lw 2
#plots the 1st function without graph legend, with lines of color -1 (black) and line width of 2 (thicker line than default)

replot f(x, 1.60, 0.46, 1.8129) notitle lt 1 lw 2
#plots the 2nd graph without erasing the first and changing only the color to 2 (red)

pause -1
#this is needed if you call gnuplot via terminal in order to have the image not disappears after few moments

lunedì 8 febbraio 2016

Skullbasher and Scriptbasher

Then comes the time when you need to use a program (PowDog) that takes as input only file with format .qpow and you only have the .xyz files.
Moreover this program wants as inline command the atom element. So you script something with bash that transforms .xyz into .qpow and then starts the program N times with different inline command each time.

Mission accomplished.


#!/bin/bash 


for f in *.xyz; do 

   awk '{t=$1; $1=$2; $2=$3; $3=$4; $4=t; print }' $f > $f.qpowd 
done 
for f in *.qpowd; do 
#the "${f%%-*}" only takes the first 2 characters of the file's name 
   ./powdog -i $f -F form.factor -e "${f%%-*}" 
done



martedì 2 febbraio 2016

I sing the parsing song

One simple format to store your atomic positions is .xyz format.
The file starts with a number (N) that tells how many atoms (and how many rows) will follow.
The remaining file is made of 4 columns with type of atom and 3 cordinates. An example is the following:

4

Pd 1 1 2.
Pd 3 1.4 1.
Pd 1 4.3 11
Pd 4 1.2 3.

Now, for every simulation or elaboration, i need to read these kind of files and, preferably, create 4 arrays one of strings and the other 3 of float.
The best thing would be to have a separate function outside the main, in order to call it when needed.
So the values must be passed by reference and not by value, using C pointers. 
The problems arise because of the clumsy way C handles strings, which basically are arrays of char.
Moreover, I do not expect the atom type to be a string of more than 5 characters, so what I need to do when passing by reference my array of strings (which is a Nx6 matrix of char) is to send a triple pointer to the function that is, actually, a double pointer to a string and everything blows up without a careful use of & and *.
Here's the result.
That's it.  It took time to get it so simply and now I am happy and I wanted to share this in order to avoid a lot of complications to those interested.



  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>


  4. void  parserxyz(char *fileneeded, double **atomx, double **atomy, double **atomz, char (**atomtype)[5], unsigned int *N)
  5. {
  6. FILE * fp;
  7. unsigned int i;
  8. fp = fopen(fileneeded, "r");
  9. if (fp == NULL) {
  10.  exit(EXIT_FAILURE);
  11. }
  12. fscanf(fp,"%u", N);
  13. *atomx = (double*) malloc(sizeof(double)*(*N));
  14. *atomy = (double*) malloc(sizeof(double)*(*N));
  15. *atomz = (double*) malloc(sizeof(double)*(*N));
  16. *atomtype= malloc(5*sizeof(char) * (*N));
  17. for (i=0; i<(*N); ++i)
  18. {
  19. fscanf(fp,"%s %lf %lf %lf", (*atomtype)[i],  &(*atomx)[i], &(*atomy)[i], &(*atomz)[i] ); 
  20. }

  21. fclose(fp);

  22. }