diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/Makefile.in | 17 | ||||
-rw-r--r-- | src/render_hkl.c | 295 |
4 files changed, 314 insertions, 4 deletions
@@ -13,4 +13,5 @@ src/hdfsee src/indexamajig src/compare_hkl src/powder_plot +src/render_hkl *~ diff --git a/src/Makefile.am b/src/Makefile.am index fcb1f2bd..d1d2c274 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = pattern_sim process_hkl get_hkl indexamajig compare_hkl \ - powder_plot + powder_plot render_hkl if HAVE_GTK bin_PROGRAMS += hdfsee @@ -46,4 +46,7 @@ powder_plot_SOURCES = powder_plot.c cell.c utils.c image.c hdf5-file.c \ detector.c powder_plot_LDADD = @LIBS@ +render_hkl_SOURCES = render_hkl.c cell.c reflections.c utils.c +render_hkl_LDADD = @LIBS@ + INCLUDES = "-I$(top_srcdir)/data" diff --git a/src/Makefile.in b/src/Makefile.in index 0ccef8a1..008e248a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -34,7 +34,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = pattern_sim$(EXEEXT) process_hkl$(EXEEXT) \ get_hkl$(EXEEXT) indexamajig$(EXEEXT) compare_hkl$(EXEEXT) \ - powder_plot$(EXEEXT) $(am__EXEEXT_1) + powder_plot$(EXEEXT) render_hkl$(EXEEXT) $(am__EXEEXT_1) @HAVE_GTK_TRUE@am__append_1 = hdfsee @HAVE_OPENCL_TRUE@am__append_2 = diffraction-gpu.c cl-utils.c @HAVE_OPENCL_TRUE@am__append_3 = diffraction-gpu.c cl-utils.c @@ -100,6 +100,10 @@ am_process_hkl_OBJECTS = process_hkl.$(OBJEXT) sfac.$(OBJEXT) \ reflections.$(OBJEXT) process_hkl_OBJECTS = $(am_process_hkl_OBJECTS) process_hkl_DEPENDENCIES = +am_render_hkl_OBJECTS = render_hkl.$(OBJEXT) cell.$(OBJEXT) \ + reflections.$(OBJEXT) utils.$(OBJEXT) +render_hkl_OBJECTS = $(am_render_hkl_OBJECTS) +render_hkl_DEPENDENCIES = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -122,11 +126,12 @@ am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(compare_hkl_SOURCES) $(get_hkl_SOURCES) $(hdfsee_SOURCES) \ $(indexamajig_SOURCES) $(pattern_sim_SOURCES) \ - $(powder_plot_SOURCES) $(process_hkl_SOURCES) + $(powder_plot_SOURCES) $(process_hkl_SOURCES) \ + $(render_hkl_SOURCES) DIST_SOURCES = $(compare_hkl_SOURCES) $(get_hkl_SOURCES) \ $(am__hdfsee_SOURCES_DIST) $(am__indexamajig_SOURCES_DIST) \ $(am__pattern_sim_SOURCES_DIST) $(powder_plot_SOURCES) \ - $(process_hkl_SOURCES) + $(process_hkl_SOURCES) $(render_hkl_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -248,6 +253,8 @@ powder_plot_SOURCES = powder_plot.c cell.c utils.c image.c hdf5-file.c \ detector.c powder_plot_LDADD = @LIBS@ +render_hkl_SOURCES = render_hkl.c cell.c reflections.c utils.c +render_hkl_LDADD = @LIBS@ INCLUDES = "-I$(top_srcdir)/data" all: all-am @@ -341,6 +348,9 @@ powder_plot$(EXEEXT): $(powder_plot_OBJECTS) $(powder_plot_DEPENDENCIES) process_hkl$(EXEEXT): $(process_hkl_OBJECTS) $(process_hkl_DEPENDENCIES) @rm -f process_hkl$(EXEEXT) $(AM_V_CCLD)$(LINK) $(process_hkl_OBJECTS) $(process_hkl_LDADD) $(LIBS) +render_hkl$(EXEEXT): $(render_hkl_OBJECTS) $(render_hkl_DEPENDENCIES) + @rm -f render_hkl$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(render_hkl_OBJECTS) $(render_hkl_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -369,6 +379,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_hkl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reflections.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render_hkl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sfac.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statistics.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ diff --git a/src/render_hkl.c b/src/render_hkl.c new file mode 100644 index 00000000..78418cc0 --- /dev/null +++ b/src/render_hkl.c @@ -0,0 +1,295 @@ +/* + * render_hkl.c + * + * Draw pretty renderings of reflection lists + * + * (c) 2006-2010 Thomas White <taw@physics.org> + * + * Part of CrystFEL - crystallography with a FEL + * + */ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <getopt.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include "utils.h" +#include "reflections.h" + + +static void show_help(const char *s) +{ + printf("Syntax: %s [options] <file.hkl>\n\n", s); + printf( +"Render intensity lists using POVray.\n" +"\n" +" -h, --help Display this help message.\n" +"\n"); +} + + +int main(int argc, char *argv[]) +{ + int c; + UnitCell *cell; + char *infile; + double *ref1; + signed int h, k, l; + unsigned int *c1; + FILE *fh; + double asx, asy, asz; + double bsx, bsy, bsz; + double csx, csy, csz; + pid_t pid; + float max; + + /* Long options */ + const struct option longopts[] = { + {"help", 0, NULL, 'h'}, + {0, 0, NULL, 0} + }; + + /* Short options */ + while ((c = getopt_long(argc, argv, "h", longopts, NULL)) != -1) { + + switch (c) { + case 'h' : { + show_help(argv[0]); + return 0; + } + + case 0 : { + break; + } + + default : { + return 1; + } + } + + } + + infile = argv[optind]; + + cell = load_cell_from_pdb("molecule.pdb"); + c1 = new_list_count(); + ref1 = read_reflections(infile, c1); + if ( ref1 == NULL ) { + ERROR("Couldn't open file '%s'\n", infile); + return 1; + } + + fh = fopen("render.pov", "w"); + fprintf(fh, "/* POV-Ray scene written by Synth3D */\n\n"); + fprintf(fh, "#include \"colors.inc\"\n"); + fprintf(fh, "#include \"textures.inc\"\n\n"); + fprintf(fh, "global_settings {\n"); + fprintf(fh, " assumed_gamma 1.0\n"); + fprintf(fh, " ambient_light 5.0\n"); + fprintf(fh, "}\n\n"); + + /* First quarter */ + fprintf(fh, "#if ( (clock >= 0) & (clock <= 124) )\n"); + fprintf(fh, "camera { location <0.0, -3.0, 0.0>" + " sky z direction 1.1*y\n" + " right -x*(image_width/image_height)\n" + " look_at <0.0, 0.0, 0.0> }\n\n"); + fprintf(fh, "#end\n"); + + /* Second quarter */ + fprintf(fh, "#if ( (clock >= 125) & (clock <= 250) )\n"); + fprintf(fh, "camera { location <0.0, -(2.0+cos((clock-125)*(180/125))), 0.0>" + " sky z direction 1.1*y\n" + " right -x*(image_width/image_height)\n" + " look_at <0.0, 0.0, 0.0> }\n\n"); + fprintf(fh, "#end\n"); + + /* Third quarter */ + fprintf(fh, "#if ( (clock >= 250) & (clock <= 374) )\n"); + fprintf(fh, "camera { location <0.0, -3.0, 0.0>" + " sky z direction 1.1*y\n" + " right -x*(image_width/image_height)\n" + " look_at <0.0, 0.0, 0.0> }\n\n"); + fprintf(fh, "#end\n"); + + /* Fourth quarter */ + fprintf(fh, "#if ( (clock >= 375) & (clock <= 500) )\n"); + fprintf(fh, "camera { location <0.0, -(2.0+cos((clock-375)*(180/125))+180), 0.0>" + " sky z direction 1.1*y\n" + " right -x*(image_width/image_height)\n" + " look_at <0.0, 0.0, 0.0> }\n\n"); + fprintf(fh, "#end\n"); + + fprintf(fh, "light_source { <-3.0 -3.0 3.0> White }\n"); + fprintf(fh, "light_source { <+3.0 -3.0 3.0> White }\n"); + fprintf(fh, "light_source { <0.0, -3.0, 0.0> 2*White }\n"); + fprintf(fh, "plane {z,-2.0 pigment { rgb <0.0, 0.0, 0.1> } }\n"); + fprintf(fh, "plane {-z,-2.0 pigment { rgb <0.0, 0.0, 0.05> } }\n\n"); + + cell_get_reciprocal(cell, &asx, &asy, &asz, + &bsx, &bsy, &bsz, + &csx, &csy, &csz); + + fprintf(fh, "#declare WC = (720/19);\n"); + + + fprintf(fh, "#declare TRANS = \n"); + fprintf(fh, "transform {\n"); + + /* First half */ + + /* Acceleration */ + fprintf(fh, "#if ( clock <= 24 )\n" + "rotate <0, 0, 0.5*WC*(clock/25)*(clock/25)>\n" + "#end\n" + + /* Cruise */ + "#if ( (clock >= 25) & (clock <= 224) )\n" + "rotate <0, 0, (WC/2)+WC*((clock-25)/25)>\n" + "#end\n" + + /* Overlap */ + + /* Deceleration */ + "#if ( (clock >= 225) & (clock <= 274) )\n" + "rotate <0, 0, 360-WC + WC*((clock-225)/25) " + " - 0.5*(WC/2)*((clock-225)/25)*((clock-225)/25) >\n" + "#end\n" + + /* Acceleration */ + "#if ( (clock >= 225) & (clock <= 274) )\n" + "rotate <0.5*(WC/2)*((clock-225)/25)*((clock-225)/25), 0, 0>\n" + "#end\n" + + /* Second half */ + + /* Cruise */ + "#if ( (clock >= 275) & (clock <= 474) )\n" + "rotate <WC+WC*((clock-275)/25), 0, 0>\n" + "#end\n" + + /* Deceleration */ + "#if ( (clock >= 475) & (clock <= 499) )\n" + "rotate <360-(WC/2)+ WC*((clock-475)/25) " + " - 0.5*WC*((clock-475)/25)*((clock-475)/25), 0, 0 >\n" + "#end\n"); + + fprintf(fh, "}\n"); + + max = 0.5e6; + for ( h=-INDMAX; h<INDMAX; h++ ) { + for ( k=-INDMAX; k<INDMAX; k++ ) { + for ( l=-INDMAX; l<INDMAX; l++ ) { + + float radius, x, y, z; + int s; + float val, p, r, g, b, trans; + + if ( !lookup_count(c1, h, k, l) ) continue; + + val = lookup_intensity(ref1, h, k, l); + + val = max-val; + + s = val / (max/6); + p = fmod(val, max/6); + p /= (max/6); + + r = 0; g = 0; b = 0; + + if ( (val < 0.0) ) { + s = 0; + p = 1.0; + } + if ( (val > max) ) { + s = 6; + } + switch ( s ) { + case 0 : { /* Black to blue */ + r = 0.0; g = 0.0; b = p; + break; + } + case 1 : { /* Blue to green */ + r = 0.0; g = p; b = 1.0-p; + break; + } + case 2 : { /* Green to red */ + r =p; g = 1.0-p; b = 0.0; + break; + } + case 3 : { /* Red to Orange */ + r = 1.0; g = 0.5*p; b = 0.0; + break; + } + case 4 : { /* Orange to Yellow */ + r = 1.0; g = 0.5 + 0.5*p; b = 0.0; + break; + } + case 5 : { /* Yellow to White */ + r = 1.0; g = 1.0; b = 1.0*p; + break; + } + case 6 : { /* Pixel has hit the maximum value */ + r = 1.0; g = 1.0; b = 1.0; + break; + } + } + + val = max-val; + + if ( val <= 0.0 ) continue; + radius = 0.1 * sqrt(sqrt(val))/1e2; + radius -= 0.005; + if ( radius > 0.03 ) radius = 0.03; + if ( radius <= 0.0 ) continue; + trans = (0.03-radius)/0.03; + radius += 0.002; + + x = asx*h + bsx*k + csx*l; + y = asy*h + bsy*k + csy*l; + z = asz*h + bsz*k + csz*l; + + fprintf(fh, "sphere { <%.5f, %.5f, %.5f>, %.5f " + "texture{pigment{color rgb <%f, %f, %f>" + " transmit %f} " + "finish { reflection 0.1 } } \n" + "transform { TRANS }\n" + "}\n", + x/1e9, y/1e9, z/1e9, radius, r, g, b, trans); + + } + } + } + + fprintf(fh, "\n"); + fclose(fh); + + pid = fork(); + if ( !( (pid != 0) && (pid != -1) ) ) { + if ( pid == -1 ) { + fprintf(stderr, "fork() failed.\n"); + } else { + /* Forked successfully, child process */ + execlp("povray", "", "+W320", "+H240", + "+Irender.pov", "+Orender.png", + "+KFI0", "+KFF499", "+KI0", "+KF499", + // "+SF220", "+EF280", + NULL); + } + } else { + int r; + waitpid(pid, &r, 0); + } + + return 0; +} |