├── CImg.h ├── COPYING ├── Makefile.am ├── Makefile.bak ├── Makefile.in ├── README.txt ├── aclocal.m4 ├── ar-lib ├── bin ├── rdf.ini.bak └── tracker.ini.bak ├── compile ├── config.guess ├── config.h.in ├── config.sub ├── configure ├── configure.ac ├── depcomp ├── graphic ├── lifFile.cpp ├── lifFile.hpp ├── lifTracker.cpp ├── lifTracker.hpp ├── mains │ ├── aquireWisdom.cpp │ ├── data2img.cpp │ ├── lifTest.cpp │ ├── tracker.cpp │ └── tracker.ini ├── radiiTracker.cpp ├── radiiTracker.hpp ├── serieTracker.cpp ├── serieTracker.hpp ├── tinyxml │ ├── readme.txt │ ├── tinystr.cpp │ ├── tinystr.h │ ├── tinyxml.cpp │ ├── tinyxml.h │ ├── tinyxmlerror.cpp │ └── tinyxmlparser.cpp ├── tracker.cpp └── tracker.hpp ├── install-sh ├── lib ├── RStarTree │ ├── RStarBoundingBox.h │ ├── RStarTree.h │ └── RStarVisitor.h ├── boo_data.cpp ├── boo_data.hpp ├── dynamicClusters.cpp ├── dynamicClusters.hpp ├── dynamicParticles.cpp ├── dynamicParticles.hpp ├── fields.cpp ├── fields.hpp ├── files_series.cpp ├── files_series.hpp ├── index.cpp ├── index.hpp ├── particles.cpp ├── particles.hpp ├── periodic.cpp ├── periodic.hpp ├── traj.cpp └── traj.hpp ├── liveTrack ├── FFT.cpp └── liveTrack2D.cpp ├── ltmain.sh ├── m4 ├── libtool.m4 ├── ltoptions.m4 ├── ltsugar.m4 ├── ltversion.m4 └── lt~obsolete.m4 ├── mains ├── ISF.cpp ├── MSD.cpp ├── all_bonds.cpp ├── avpos.cpp ├── bonds.cpp ├── boo.cpp ├── boo5.cpp ├── boo_flip.cpp ├── cage2vtk.cpp ├── cgVoro.cpp ├── cutter.cpp ├── dat2vtk.cpp ├── dhlngb.cpp ├── drift.cpp ├── dynamics.cpp ├── g6.cpp ├── linkboo.cpp ├── linker.cpp ├── lostngb.cpp ├── percolation.cpp ├── rdf.cpp ├── sp5c.cpp ├── totalRdf.cpp └── traj2vtk.cpp ├── missing ├── multiscale ├── Debug │ ├── makefile │ ├── objects.mk │ ├── sources.mk │ ├── src │ │ └── subdir.mk │ ├── subdir.mk │ └── test │ │ └── subdir.mk ├── RStarTree │ ├── RStarBoundingBox.h │ ├── RStarTree.h │ └── RStarVisitor.h ├── Release │ ├── makefile │ ├── objects.mk │ ├── sources.mk │ ├── src │ │ └── subdir.mk │ ├── subdir.mk │ └── test │ │ └── subdir.mk ├── main.cpp ├── src │ ├── center.hpp │ ├── deconvolution.cpp │ ├── deconvolution.hpp │ ├── lifFile.cpp │ ├── lifFile.hpp │ ├── locatorfromlif.cpp │ ├── locatorfromlif.hpp │ ├── multiscalefinder.cpp │ ├── multiscalefinder.hpp │ ├── octavefinder.cpp │ ├── octavefinder.hpp │ ├── reconstructor.cpp │ ├── reconstructor.hpp │ ├── traj.cpp │ └── traj.hpp ├── test │ ├── deconvolution.cpp │ ├── lif.cpp │ ├── lifTrack.cpp │ ├── main.cpp │ ├── oneD.cpp │ ├── overlap.cpp │ ├── reconstruction.cpp │ ├── threeD.cpp │ ├── trajectories.cpp │ └── twoD.cpp └── test_input │ ├── 3d_6_0.54_0.dat │ ├── Gel_3_9_15_decon2.lif │ ├── Playing_JH2.lif │ ├── Z_elong.raw │ ├── Z_preblur.raw │ ├── gel.raw │ ├── poly00_phi05.dat │ ├── real.blob │ └── real2.blob ├── python ├── boo │ └── boo.py └── colloids │ ├── __init__.py │ ├── clouds.py │ ├── colors.py │ ├── count_nuclei.py │ ├── cython │ ├── boo.ipynb │ ├── periodic.ipynb │ ├── periodic.pyx │ ├── setup.py │ └── structure_factor.pyx │ ├── ddm.py │ ├── depreciated │ ├── __init__.py │ └── boo.py │ ├── dillute_raw.npy │ ├── displ2D.py │ ├── experiment.py │ ├── h52traj.py │ ├── lif.py │ ├── lif2vtk.py │ ├── lifTest.py │ ├── microrheology.py │ ├── notebooks │ ├── CrockerGrier.ipynb │ ├── Deconvolution.ipynb │ ├── Multiscale.html │ ├── Multiscale.ipynb │ ├── Multiscale.md │ ├── Radii of gyration.ipynb │ ├── droplets.jpg │ └── phase diagram.ipynb │ ├── particles.py │ ├── periodic.py │ ├── phase.py │ ├── phaseCorrelation.py │ ├── povray.py │ ├── progressbar.py │ ├── spectrum.py │ ├── statistics.py │ ├── test_particles.py │ ├── track.py │ ├── track_droplet.py │ ├── track_orange.py │ ├── traj2h5.py │ ├── truc.py │ ├── voro.py │ └── vtk.py ├── test ├── main.cpp ├── serietracker.cpp └── tracker.cpp ├── test_input ├── TSerie_t000.tif ├── ZSerie_z00.tif ├── ZSerie_z01.tif ├── ZSerie_z02.tif ├── ZSerie_z03.tif ├── ZSerie_z04.tif ├── ZSerie_z05.tif ├── ZSerie_z06.tif ├── ZSerie_z07.tif ├── ZSerie_z08.tif ├── ZSerie_z09.tif ├── ZSerie_z10.tif ├── ZSerie_z11.tif ├── ZSerie_z12.tif ├── ZSerie_z13.tif ├── ZSerie_z14.tif ├── ZSerie_z15.tif ├── ZTSerie_z00_t000.tif ├── ZTSerie_z01_t000.tif ├── ZTSerie_z02_t000.tif ├── ZTSerie_z03_t000.tif ├── ZTSerie_z04_t000.tif ├── ZTSerie_z05_t000.tif ├── ZTSerie_z06_t000.tif ├── ZTSerie_z07_t000.tif ├── ZTSerie_z08_t000.tif ├── ZTSerie_z09_t000.tif ├── ZTSerie_z10_t000.tif ├── ZTSerie_z11_t000.tif ├── ZTSerie_z12_t000.tif ├── ZTSerie_z13_t000.tif ├── ZTSerie_z14_t000.tif ├── ZTSerie_z15_t000.tif └── single_image.tif ├── tracker.cbp.linux └── tracker.cbp.win /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | 3 | lib_LTLIBRARIES = libcolloids.la libcolloids-graphic.la 4 | 5 | include_HEADERS = lib/boo_data.hpp lib/fields.hpp lib/particles.hpp lib/dynamicClusters.hpp lib/files_series.hpp lib/periodic.hpp lib/dynamicParticles.hpp lib/index.hpp lib/traj.hpp graphic/lifFile.hpp graphic/lifTracker.hpp graphic/radiiTracker.hpp graphic/serieTracker.hpp graphic/tracker.hpp 6 | 7 | libcolloids_la_SOURCES = lib/boo_data.cpp lib/fields.cpp lib/particles.cpp lib/dynamicClusters.cpp lib/files_series.cpp lib/periodic.cpp lib/dynamicParticles.cpp lib/index.cpp lib/traj.cpp lib/boo_data.hpp lib/fields.hpp lib/particles.hpp lib/dynamicClusters.hpp lib/files_series.hpp lib/periodic.hpp lib/dynamicParticles.hpp lib/index.hpp lib/traj.hpp lib/RStarTree/RStarBoundingBox.h lib/RStarTree/RStarTree.h lib/RStarTree/RStarVisitor.h 8 | 9 | LDADD = libcolloids.la 10 | AM_CPPFLAGS = -I$(srcdir)/lib -I$(srcdir)/graphic -DTIXML_USE_STL 11 | bin_PROGRAMS = all_bonds bonds boo boo_flip cage2vtk cutter dat2vtk dhlngb drift dynamics g6 ISF linkboo linker lostngb MSD percolation rdf sp5c totalRdf traj2vtk periodic_rdf periodic_boo periodic_g6 $(binvoro) aquireWisdom tracker tests 12 | 13 | EXTRA_PROGRAMS = cgVoro periodic_cgVoro 14 | periodic_boo_CPPFLAGS = $(AM_CPPFLAGS) -Duse_periodic 15 | periodic_rdf_CPPFLAGS = $(AM_CPPFLAGS) -Duse_periodic 16 | periodic_g6_CPPFLAGS = $(AM_CPPFLAGS) -Duse_periodic 17 | cgVoro_CPPFLAGS = $(AM_CPPFLAGS) -I$(VORO_SRC) 18 | periodic_cgVoro_CPPFLAGS = $(cgVoro_CPPFLAGS) -Duse_periodic 19 | 20 | all_bonds_SOURCES = mains/all_bonds.cpp 21 | bonds_SOURCES = mains/bonds.cpp 22 | boo_SOURCES = mains/boo.cpp 23 | periodic_boo_SOURCES = mains/boo.cpp 24 | boo_flip_SOURCES = mains/boo_flip.cpp 25 | cage2vtk_SOURCES = mains/cage2vtk.cpp 26 | cgVoro_SOURCES = mains/cgVoro.cpp 27 | periodic_cgVoro_SOURCES = mains/cgVoro.cpp 28 | cutter_SOURCES = mains/cutter.cpp 29 | dat2vtk_SOURCES = mains/dat2vtk.cpp 30 | dhlngb_SOURCES = mains/dhlngb.cpp 31 | drift_SOURCES = mains/drift.cpp 32 | dynamics_SOURCES = mains/dynamics.cpp 33 | g6_SOURCES = mains/g6.cpp 34 | periodic_g6_SOURCES = mains/g6.cpp 35 | ISF_SOURCES = mains/ISF.cpp 36 | linkboo_SOURCES = mains/linkboo.cpp 37 | linker_SOURCES = mains/linker.cpp 38 | lostngb_SOURCES = mains/lostngb.cpp 39 | MSD_SOURCES = mains/MSD.cpp 40 | percolation_SOURCES = mains/percolation.cpp 41 | rdf_SOURCES = mains/rdf.cpp 42 | periodic_rdf_SOURCES = mains/rdf.cpp 43 | sp5c_SOURCES = mains/sp5c.cpp 44 | totalRdf_SOURCES = mains/totalRdf.cpp 45 | traj2vtk_SOURCES = mains/traj2vtk.cpp 46 | 47 | cutter_LDFLAGS = $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) 48 | 49 | 50 | libcolloids_graphic_la_SOURCES = graphic/lifFile.cpp graphic/lifFile.hpp graphic/lifTracker.cpp graphic/lifTracker.hpp graphic/radiiTracker.cpp graphic/radiiTracker.hpp graphic/serieTracker.cpp graphic/serieTracker.hpp graphic/tracker.cpp graphic/tracker.hpp graphic/tinyxml/tinystr.h graphic/tinyxml/tinyxmlerror.cpp graphic/tinyxml/tinyxmlparser.cpp graphic/tinyxml/tinystr.cpp graphic/tinyxml/tinyxml.cpp graphic/tinyxml/tinyxml.h 51 | 52 | LDADD += libcolloids-graphic.la 53 | 54 | aquireWisdom_SOURCES = graphic/mains/aquireWisdom.cpp 55 | tracker_SOURCES = graphic/mains/tracker.cpp 56 | 57 | tracker_LDFLAGS = $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) 58 | 59 | tests_SOURCES = test/main.cpp test/tracker.cpp test/serietracker.cpp 60 | LDADD += -lboost_unit_test_framework 61 | -------------------------------------------------------------------------------- /Makefile.bak: -------------------------------------------------------------------------------- 1 | # generated by cbp2makefile.py 2 | # see http://pix.test.at/wiki/cbp2makefile for more info 3 | 4 | #directory tree related. Must be adapted for each machine 5 | OUTPUT_DIR = /home/mathieu/bin/ 6 | #OUTPUT_DIR = ./ 7 | #BOOST_DIR = /home/mathieu/boost 8 | BOOST_DIR = /usr/local/boost 9 | VORO_DIR = /home/mathieu/src/voro++/src 10 | CIMG_DIR = /home/mathieu/src/CImg-1.3.1 11 | 12 | #complier related 13 | CPP = icpc 14 | CXXFLAGS += -O3 -Wall -I $(BOOST_DIR) -I$(VORO_DIR) -I$(CIMG_DIR) -DTIXML_USE_STL -Dcimg_use_tiff -Dcimg_use_fftw3 -DINSTAL_PATH=\"$(OUTPUT_DIR)\" -DTRACKER_N_THREADS=6 15 | LDFLAGS += -L$(OUTPUT_DIR) -L/home/lib 16 | ifeq ($(CPP),icpc) 17 | CXXFLAGS += -w1 -xT -parallel -use-intel-optimized-headers -L$(MKLPATH) $(MKLPATH)/libmkl_solver_lp64.a -Wl,--start-group -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -Wl,--end-group -openmp -lpthread 18 | endif 19 | 20 | #OS related 21 | OS=nux 22 | LIB_BASE_NAME = particles 23 | GRAPHIC_LIB_BASE_NAME = graphic_$(LIB_BASE_NAME) 24 | ifeq ($(OS),win) 25 | SONAME = $(LIB_BASE_NAME).dll 26 | GRAPHIC_SONAME = $(GRAPHIC_LIB_BASE_NAME).dll 27 | EXT = .exe 28 | MKDIR_COMMAND = 29 | else 30 | SONAME = lib$(LIB_BASE_NAME).so 31 | GRAPHIC_SONAME = lib$(GRAPHIC_LIB_BASE_NAME).so 32 | EXT = 33 | MKDIR_COMMAND = -p 34 | endif 35 | LIB_NAME = $(OUTPUT_DIR)$(SONAME) 36 | LIB_GRAPHIC_NAME = $(OUTPUT_DIR)$(GRAPHIC_SONAME) 37 | LIBS += -l$(LIB_BASE_NAME) 38 | LIBS_GRAPHIC = $(LIBS) -lgdi32 -ltiff -lfftw3f -lboost_program_options -lX11 39 | #GRAPHIC_FLAGS = -Dcimg_use_tiff -Dcimg_use_fftw3 -DINSTAL_PATH=\"$(OUTPUT_DIR)\" 40 | 41 | #following option is -DLINUX even under MinGW 42 | CXXFLAGS += -DLINUX 43 | OBJ_OUTPUT = objs/ 44 | 45 | 46 | SRC := $(wildcard *.cpp) 47 | HEADERS := $(wildcard *.hpp) 48 | OBJ := $(addprefix $(OBJ_OUTPUT), $(SRC:.cpp=.o) ) 49 | TARGETS := $(notdir $(basename $(wildcard mains/*.cpp))) 50 | 51 | SRC_PERIODIC := rdf.cpp boo.cpp 52 | OBJ_PERIODIC := $(addprefix $(OBJ_OUTPUT)mains/periodic_, $(SRC_PERIODIC:.cpp=.o) ) 53 | TARGETS_PERIODIC := $(addprefix periodic_, $(basename $(SRC_PERIODIC))) 54 | 55 | SRC_GRAPHIC := $(wildcard graphic/*.cpp) 56 | HEADER_GRAPHIC := $(wildcard graphic/*.hpp) 57 | OBJ_GRAPHIC := $(addprefix $(OBJ_OUTPUT), $(SRC_GRAPHIC:.cpp=.o) ) 58 | TARGETS_GRAPHIC := $(notdir $(basename $(wildcard graphic/mains/*.cpp))) 59 | 60 | SRC_TINYXML := $(addprefix tinyxml/, tinyxml.cpp tinyxmlparser.cpp tinyxmlerror.cpp tinystr.cpp) 61 | OBJ_TINYXML := $(addprefix $(OBJ_OUTPUT), $(SRC_TINYXML:.cpp=.o) ) 62 | 63 | all: library graphiclibrary $(TARGETS) $(TARGETS_PERIODIC) 64 | 65 | library: $(LIB_NAME) 66 | 67 | graphiclibrary: $(LIB_GRAPHIC_NAME) $(LIB_NAME) 68 | 69 | $(LIB_NAME): $(OBJ) 70 | -@mkdir $(MKDIR_COMMAND) $(OUTPUT_DIR) 71 | @$(CPP) -o $@ -shared $(CXXFLAGS) $^ 72 | 73 | $(LIB_GRAPHIC_NAME): $(OBJ_GRAPHIC) $(OBJ_TINYXML) 74 | -@mkdir $(MKDIR_COMMAND) $(OUTPUT_DIR) 75 | @$(CPP) -o $@ -shared $^ $(LDFLAGS) $(LIBS_GRAPHIC) $(GRAPHIC_FLAGS) 76 | 77 | #making the target "c:/bin/target.exe" a dependency of the target "target" 78 | $(foreach tar,$(TARGETS) $(TARGETS_PERIODIC) $(TARGETS_GRAPHIC),$(eval $(tar): $(OUTPUT_DIR)$(tar)$(EXT)) ) 79 | 80 | #linking of each target 81 | $(foreach tar,$(TARGETS) $(TARGETS_PERIODIC),$(eval $(OUTPUT_DIR)$(tar)$(EXT): $(OBJ_OUTPUT)mains/$(tar).o $(LIB_NAME) ; $(CPP) -o $$@ $$< $(LDFLAGS) $(LIBS) $(CXXFLAGS))) 82 | $(foreach tar,$(TARGETS_GRAPHIC),$(eval $(OUTPUT_DIR)$(tar)$(EXT): $(OBJ_OUTPUT)graphic/mains/$(tar).o graphiclibrary; $(CPP) -o $$@ $$< $(LDFLAGS) $(GRAPHIC_FLAGS) $(LIBS_GRAPHIC) -l$(GRAPHIC_LIB_BASE_NAME))) 83 | 84 | $(OBJ_OUTPUT)%.o: %.cpp $(HEADERS) 85 | -@mkdir $(MKDIR_COMMAND) $(OBJ_OUTPUT) 86 | @$(CPP) -o $@ -c $< -fPIC $(CXXFLAGS) 87 | 88 | $(OBJ_OUTPUT)graphic/%.o: graphic/%.cpp %.hpp $(HEADERS) 89 | -@mkdir $(MKDIR_COMMAND) $(OBJ_OUTPUT)graphic 90 | @$(CPP) -o $@ -c $< -fPIC $(CXXFLAGS) $(GRAPHIC_FLAGS) 91 | 92 | $(OBJ_OUTPUT)mains/%.o: mains/%.cpp 93 | -@mkdir $(MKDIR_COMMAND) $(OBJ_OUTPUT)mains 94 | @$(CPP) -o $@ -c $< $(CXXFLAGS) $(GRAPHIC_FLAGS) 95 | 96 | $(OBJ_OUTPUT)graphic/mains/%.o: graphic/mains/%.cpp $(HEADERS) 97 | -@mkdir $(MKDIR_COMMAND) $(OBJ_OUTPUT)graphic/mains 98 | @$(CPP) -o $@ -c $< $(CXXFLAGS) $(GRAPHIC_FLAGS) 99 | 100 | $(OBJ_OUTPUT)mains/periodic_%.o: mains/%.cpp 101 | -@mkdir $(MKDIR_COMMAND) $(OBJ_OUTPUT)mains 102 | @$(CPP) -o $@ -c $< $(CXXFLAGS) -Duse_periodic 103 | 104 | $(OBJ_OUTPUT)tinyxml/%.o: tinyxml/%.cpp 105 | -@mkdir $(MKDIR_COMMAND) $(OBJ_OUTPUT)tinyxml 106 | @$(CPP) -o $@ -c $< -fPIC $(CXXFLAGS) $(GRAPHIC_FLAGS) 107 | 108 | clean: cleanlibrary cleangraphiclibrary $(addprefix clean, $(TARGETS) $(TARGETS_PERIODIC)) 109 | 110 | cleanlibrary: 111 | -@rm -rf $(OBJ_OUTPUT)*.o 112 | 113 | cleangraphiclibrary: cleantinyxml 114 | -@rm -rf $(OBJ_OUTPUT)graphic/*.o 115 | 116 | cleantinyxml: 117 | -@rm -rf $(OBJ_OUTPUT)tinyxml/*.o 118 | 119 | #cleaning each target 120 | $(foreach tar,$(TARGETS) $(TARGETS_PERIODIC),$(eval clean$(tar): cleanlibrary; -@rm -rf $(OBJ_OUTPUT)mains/$(tar).o) ) 121 | $(foreach tar,$(TARGETS_GRAPHIC),$(eval clean$(tar): cleanlibrary cleangraphiclibrary; -@rm -rf $(OBJ_OUTPUT)graphic/mains/$(tar).o) ) 122 | 123 | mrproper: clean 124 | -@($(foreach tar, $(TARGETS) $(TARGETS_PERIODIC), rm -rf $(OUTPUT_DIR)$(tar)$(EXT) &&) rm -rf $(LIB_NAME)) 125 | 126 | 127 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | ********** 2 | *COLLOIDS* 3 | ********** 4 | 5 | Description 6 | 7 | Colloids is a C++ library to process both experimental and simulation data of colloidal particles. 8 | The main features are 9 | 10 | * particle tracking from confocal microscopy images 11 | * analysis of local structure and dynamics of particles (from simulations or experiments) 12 | 13 | 14 | Project Homepage 15 | 16 | The project has a homepage which can be found at https://github.com/MathieuLeocmach/colloids/wiki 17 | 18 | Copyright and License 19 | 20 | Copyright 2008,2009 Mathieu Leocmach 21 | 22 | This file is part of Colloids. 23 | 24 | Colloids is free software: you can redistribute it and/or modify 25 | it under the terms of the GNU General Public License as published by 26 | the Free Software Foundation, either version 3 of the License, or 27 | (at your option) any later version. 28 | 29 | Colloids is distributed in the hope that it will be useful, 30 | but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 | GNU General Public License for more details. 33 | 34 | You should have received a copy of the GNU General Public License 35 | along with Colloids. If not, see . 36 | 37 | 38 | Aknowledge please 39 | 40 | Please cite Colloids and it's author(s) in any scientific publication using this software. 41 | 42 | The code in itself has a DOI number so you can cite it. Bibtex entry could be something like 43 | 44 | @misc{ 45 | Leocmach2015, 46 | title={The colloid toolkit}, 47 | url={http://dx.doi.org/10.5281/zenodo.31286}, 48 | DOI={10.5281/zenodo.31286}, 49 | author={Mathieu Leocmach}, 50 | year={2015} 51 | } 52 | 53 | The multiscale algorithm is described in 54 | 55 | @Article{Leocmach2013, 56 | author ="Leocmach, Mathieu and Tanaka, Hajime", 57 | title ="A novel particle tracking method with individual particle size measurement and its application to ordering in glassy hard sphere colloids", 58 | journal ="Soft Matter", 59 | year ="2013", 60 | volume ="9", 61 | issue ="5", 62 | pages ="1447-1457", 63 | publisher ="The Royal Society of Chemistry", 64 | doi ="10.1039/C2SM27107A", 65 | } 66 | 67 | 68 | Contact 69 | Mathieu LEOCMACH, Institut Lumière Matière, UMR-CNRS 5306, Lyon, France 70 | mathieu.leocmach AT polytechnique.org 71 | -------------------------------------------------------------------------------- /ar-lib: -------------------------------------------------------------------------------- 1 | /usr/share/automake-1.14/ar-lib -------------------------------------------------------------------------------- /bin/rdf.ini.bak: -------------------------------------------------------------------------------- 1 | 2 | tsize=1 3 | toffset=0 4 | nbdigit_t=0 5 | inputPath = c:/data/kawasaki_output/gauss_ 6 | 7 | 8 | nbDiameterCutOff=6 9 | Nbins=100 10 | radius = 5 -------------------------------------------------------------------------------- /bin/tracker.ini.bak: -------------------------------------------------------------------------------- 1 | # Tracking configuration 2 | input=C:/Code_data/YLP4 100% H+1/crystal1_z000_ch00.tif 3 | outputPath = C:/Code_output/YLP4 100% H+1/crystal1_ 4 | displayRadius = 4.8 5 | radiusMin = 3.48 6 | radiusMax = 64 7 | zradiusMin = 3.48 8 | zradiusMax = 64 9 | threshold = 90 10 | 11 | # Specific to file serie mode 12 | channel = 1 13 | xsize = 256 14 | ysize = 256 15 | zsize = 128 16 | tsize = 1 17 | zoffset = 0 18 | toffset = 0 19 | voxelWidth = 1 20 | voxelDepth = 1 21 | 22 | -------------------------------------------------------------------------------- /compile: -------------------------------------------------------------------------------- 1 | /usr/share/automake-1.14/compile -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* define if the Boost library is available */ 4 | #undef HAVE_BOOST 5 | 6 | /* define if the Boost::PROGRAM_OPTIONS library is available */ 7 | #undef HAVE_BOOST_PROGRAM_OPTIONS 8 | 9 | /* Define to 1 if you have the header file. */ 10 | #undef HAVE_DLFCN_H 11 | 12 | /* Define to 1 if you have the header file. */ 13 | #undef HAVE_INTTYPES_H 14 | 15 | /* Define to 1 if you have the `fftw3f' library (-lfftw3f). */ 16 | #undef HAVE_LIBFFTW3F 17 | 18 | /* Define to 1 if you have the `fftw3f_threads' library (-lfftw3f_threads). */ 19 | #undef HAVE_LIBFFTW3F_THREADS 20 | 21 | /* Define to 1 if you have the `m' library (-lm). */ 22 | #undef HAVE_LIBM 23 | 24 | /* Define to 1 if you have the 'pthread' library (-lpthread). */ 25 | #undef HAVE_LIBNCURSES 26 | 27 | /* Define to 1 if you have the `X11' library (-lX11). */ 28 | #undef HAVE_LIBX11 29 | 30 | /* Define to 1 if you have the header file. */ 31 | #undef HAVE_MEMORY_H 32 | 33 | /* Define to 1 if you have the header file. */ 34 | #undef HAVE_PTHREAD_H 35 | 36 | /* Define to 1 if you have the header file. */ 37 | #undef HAVE_STDINT_H 38 | 39 | /* Define to 1 if you have the header file. */ 40 | #undef HAVE_STDLIB_H 41 | 42 | /* Define to 1 if you have the header file. */ 43 | #undef HAVE_STRINGS_H 44 | 45 | /* Define to 1 if you have the header file. */ 46 | #undef HAVE_STRING_H 47 | 48 | /* Define to 1 if you have the header file. */ 49 | #undef HAVE_SYS_STAT_H 50 | 51 | /* Define to 1 if you have the header file. */ 52 | #undef HAVE_SYS_TYPES_H 53 | 54 | /* Define to 1 if you have the header file. */ 55 | #undef HAVE_UNISTD_H 56 | 57 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 58 | */ 59 | #undef LT_OBJDIR 60 | 61 | /* Name of package */ 62 | #undef PACKAGE 63 | 64 | /* Define to the address where bug reports for this package should be sent. */ 65 | #undef PACKAGE_BUGREPORT 66 | 67 | /* Define to the full name of this package. */ 68 | #undef PACKAGE_NAME 69 | 70 | /* Define to the full name and version of this package. */ 71 | #undef PACKAGE_STRING 72 | 73 | /* Define to the one symbol short name of this package. */ 74 | #undef PACKAGE_TARNAME 75 | 76 | /* Define to the home page for this package. */ 77 | #undef PACKAGE_URL 78 | 79 | /* Define to the version of this package. */ 80 | #undef PACKAGE_VERSION 81 | 82 | /* Define to 1 if you have the ANSI C header files. */ 83 | #undef STDC_HEADERS 84 | 85 | /* Version number of package */ 86 | #undef VERSION 87 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | #note: need autoconf and autoconf-archive installed 2 | AC_INIT([colloids], [1.0], [mathieu@iis.u-tokyo.ac.jp]) 3 | AC_CANONICAL_HOST 4 | AC_CONFIG_MACRO_DIR([m4]) 5 | AM_INIT_AUTOMAKE([subdir-objects foreign -Wall -Werror]) 6 | m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) 7 | AC_LIBTOOL_WIN32_DLL 8 | 9 | AC_PROG_CXX 10 | AC_LANG([C++]) 11 | AC_CONFIG_SRCDIR([lib/particles.hpp]) 12 | AC_CONFIG_HEADERS([config.h]) 13 | #AC_CONFIG_SUBDIRS([mains graphic]) 14 | AC_CONFIG_FILES([Makefile]) 15 | LT_INIT 16 | AM_MAINTAINER_MODE([disable]) 17 | #AX_MAINTAINER_MODE_AUTO_SILENT 18 | 19 | dnl get the flags 20 | CXXFLAGS="${CXXFLAGS=}" 21 | dnl this macro is used to get the arguments supplied 22 | dnl to the configure script (./configure --enable-debug) 23 | dnl Check if we have enable debug support. 24 | AC_MSG_CHECKING(whether to enable debugging) 25 | debug_default="no" 26 | AC_ARG_ENABLE(debug, [ --enable-debug=[no/yes] turn on debugging 27 | [default=$debug_default]],, enable_debug=$debug_default) 28 | dnl Yes, shell scripts can be used 29 | if test "x$enable_debug" = "xyes"; then 30 | CXXFLAGS="$CXXFLAGS -g -DDEBUG" 31 | AC_MSG_RESULT(yes) 32 | else 33 | CXXFLAGS="$CXXFLAGS -O3 -Wall -DNDEBUG" 34 | AC_MSG_RESULT(no) 35 | fi 36 | 37 | #Try to recognize the architecture 38 | AX_GCC_ARCHFLAG([yes], [CXXFLAGS="$CXXFLAGS $ax_cv_gcc_archflag"]) 39 | 40 | lt_enable_auto_import="" 41 | case "$host_os" in 42 | mingw* | cegcc*) 43 | LDFLAGS="$LDFLAGS -Wl,--enable-auto-import -lgdi32" 44 | esac 45 | AC_SUBST(lt_enable_auto_import) 46 | 47 | 48 | AX_BOOST_BASE([1.35], , AC_MSG_ERROR('boost >1.35 is needed to calculate spherical harmonics')) 49 | AX_BOOST_PROGRAM_OPTIONS 50 | 51 | if test "x$want_boost" = "xno"; then 52 | AC_MSG_ERROR('boost >1.35 is needed to calculate spherical harmonics. Use --with-boost and --with-boost-program-options.') 53 | fi 54 | 55 | AC_CHECK_HEADER([CImg.h], , AC_MSG_ERROR('CImg >1.32 is needed')) 56 | 57 | AX_COUNT_CPUS 58 | CPPFLAGS="$CPPFLAGS -DTRACKER_N_THREADS=$CPU_COUNT" 59 | 60 | AC_OPENMP 61 | if test "$OPENMP_CXXFLAGS" != ""; then 62 | CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" 63 | CPPFLAGS="$CPPFLAGS -Dcimg_use_openmp" 64 | fi 65 | 66 | # Checks for pthread. 67 | AC_CHECK_HEADERS([pthread.h], [ 68 | AC_CHECK_LIB(pthread, pthread_create, [ 69 | LIBS="$LIBS -lpthread" 70 | AC_DEFINE(HAVE_LIBNCURSES, 1, [Define to 1 if you have the 'pthread' library (-lpthread).]) 71 | ]) 72 | ]) 73 | 74 | if test "$PTHREAD_LIBS" != ""; then 75 | LIBS="$PTHREAD_LIBS $LIBS" 76 | CXXFLAGS="$CXXFLAGS $PTHREAD_CXXFLAGS" 77 | CC="$PTHREAD_CC" 78 | fi 79 | 80 | #FFTW 81 | AC_CHECK_HEADER([fftw3.h], , AC_MSG_ERROR('FFTW >3 is needed')) 82 | AC_CHECK_LIB([fftw3f], [fftwf_free]) 83 | #Under windows, fftw thread's functions are included into the main library, thus this will fail silently 84 | AC_CHECK_LIB([fftw3f_threads], [fftwf_init_threads]) 85 | 86 | #Display Unix 87 | AC_CHECK_LIB([X11], [XOpenDisplay]) 88 | #No need to check the display on Windows: the API is automatically linked 89 | #AC_CHECK_LIB([gdi32],[GetPixel]) 90 | #Math library 91 | AC_CHECK_LIB([m], [sqrt]) 92 | 93 | AC_ARG_WITH(voro-src, [ --with-voro-src=DIR Voro++ source files are in DIR]) 94 | if test $with_voro_src; then 95 | AC_CHECK_FILE( 96 | [$with_voro_src/voro++.cc], 97 | [ 98 | voro=true 99 | AC_SUBST(VORO_SRC, $with_voro_src) 100 | AC_SUBST(binvoro, "cgVoro periodic_cgVoro") 101 | ], 102 | [AC_MSG_ERROR("No voro++.cc at the indicated path")] 103 | ) 104 | fi 105 | AM_CONDITIONAL([WANT_VORO],[test x$voro = xtrue]) 106 | 107 | AC_OUTPUT 108 | -------------------------------------------------------------------------------- /graphic/lifTracker.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2008,2009 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | 19 | * \file lifTracker.hpp 20 | * \brief glue between Tracker and LifFile 21 | * \author Mathieu Leocmach 22 | * \version 0.1 23 | * \date 22 december 2009 24 | * 25 | * 26 | */ 27 | 28 | #include 29 | #include "lifTracker.hpp" 30 | 31 | using namespace std; 32 | using namespace Colloids; 33 | 34 | /** @brief Constructor from an existant LifFile object */ 35 | LifTracker::LifTracker(LifSerie &serie, const size_t ch, const unsigned fs) 36 | { 37 | this->serie = &serie; 38 | setChannel(ch); 39 | tracker = new Tracker(getTrackerDims(), fs); 40 | tracker->fortran_order=true; 41 | this->centers=0; 42 | unsetThreshold(); 43 | setTimeStep(0); 44 | return; 45 | } 46 | 47 | /** @brief chooseChannel */ 48 | void LifTracker::chooseChannel() 49 | { 50 | channel = getLif().chooseChannel(); 51 | } 52 | 53 | /** @brief set the current time step */ 54 | void LifTracker::setTimeStep(size_t t) 55 | { 56 | this->iterator = serie->begin(t); 57 | this->time_step = t; 58 | if(centers) 59 | { 60 | Particles* old_centers = this->centers; 61 | this->centers = 0; 62 | delete old_centers; 63 | } 64 | tracker->fillImage_charToUchar(this->iterator); 65 | } 66 | 67 | 68 | 69 | 70 | /** @brief Fill the tracker's image with the next time step */ 71 | LifTracker & LifTracker::operator++() 72 | { 73 | if(!quiet()) cout<<"to t="<iterator != std::istreambuf_iterator()) 75 | this->iterator = tracker->fillImage_charToUchar(this->iterator); 76 | if(centers) 77 | { 78 | Particles* old_centers = this->centers; 79 | this->centers = 0; 80 | delete old_centers; 81 | } 82 | this->time_step++; 83 | return *this; 84 | } 85 | 86 | 87 | 88 | 89 | /** @brief get the dimensions according to the content of the lif serie 90 | Convert the dimension order from row major (Leica files) to column major (c order) 91 | If less than 3 dimensions, the first(s) dimension(s) is/are set to 1. 92 | That way (last dim != 1), real to complex FFT is efficient. 93 | */ 94 | boost::array LifTracker::getTrackerDims() const 95 | { 96 | boost::array dims = {{1,1,1}}; 97 | vector fortran_order_dims = getLif().getSpatialDimensions(); 98 | copy( 99 | fortran_order_dims.begin(), 100 | fortran_order_dims.end(), 101 | dims.rbegin() 102 | ); 103 | return dims; 104 | } 105 | 106 | 107 | /** @brief get the dimensions according to the content of the lif serie 108 | Convert the dimension order from row major (Leica files) to column major (c order) 109 | If less than 3 dimensions, the first(s) dimension(s) is/are set to 1. 110 | That way (last dim != 1), real to complex FFT is efficient. 111 | */ 112 | /*boost::array LifTracker2D::getTrackerDims() const 113 | { 114 | boost::array dims = {1,1,1}; 115 | vector fortran_order_dims = getLif().getSpatialDimensions(); 116 | fortran_order_dims.back()=1; 117 | copy( 118 | fortran_order_dims.begin(), 119 | fortran_order_dims.end(), 120 | dims.rbegin() 121 | ); 122 | return dims; 123 | }*/ 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /graphic/lifTracker.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2008,2009 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | 19 | * \file lifTracker.hpp 20 | * \author Mathieu Leocmach 21 | * \version 0.1 22 | * \date 22 december 2009 23 | * 24 | * 25 | */ 26 | 27 | #ifndef lif_tracker_H 28 | #define lif_tracker_file_H 29 | 30 | #include "tracker.hpp" 31 | #include "lifFile.hpp" 32 | namespace Colloids{ 33 | /** \brief glue between Tracker and LifFile 34 | Can be used as a stadard InputIterator 35 | */ 36 | class LifTracker : public TrackerIterator 37 | { 38 | LifSerie *serie; 39 | std::istreambuf_iterator iterator; 40 | 41 | public: 42 | explicit LifTracker(LifSerie &serie, const size_t ch=0, const unsigned fs=FFTW_ESTIMATE); 43 | /** \brief default constructor that should be used only to get an "end" iterator*/ 44 | LifTracker end(){return LifTracker(getLif().getNbTimeSteps());}; 45 | bool reachedEnd(){return getTimeStep()>=getLif().getNbTimeSteps();}; 46 | 47 | LifSerie& getLif() const {return *serie;}; 48 | 49 | void chooseChannel(); 50 | void setTimeStep(size_t t); 51 | double getZXratio(){return serie->getZXratio();}; 52 | 53 | LifTracker& operator++(); 54 | bool operator==(const LifTracker& rhs) {return time_step==rhs.time_step && serie==rhs.serie;} 55 | bool operator!=(const LifTracker& rhs) {return time_step!=rhs.time_step;} 56 | 57 | 58 | private: 59 | LifTracker(const size_t end_step) : iterator(){time_step = end_step;}; 60 | boost::array getTrackerDims() const; 61 | std::streampos tellg(){return serie->tellg();} 62 | 63 | }; 64 | 65 | /** \brief A slice by slice version of the previous 66 | */ 67 | /*class LifTracker2D : public LifTracker 68 | { 69 | public: 70 | explicit LifTracker2D(LifSerie &serie, const size_t ch=0, const unsigned fs=FFTW_ESTIMATE) : LifTracker(serie, ch, fs){}; 71 | // \brief default constructor that should be used only to get an "end" iterator 72 | LifTracker2D end(){return LifTracker2D(getLif().getNbTimeSteps()*getLif().getSpatialDimensions()[0]);}; 73 | 74 | bool operator==(const LifTracker2D& rhs) {return time_step==rhs.time_step && getLif()==rhs.getLif();} 75 | //bool operator!=(const LifTracker& rhs) {return time_step!=rhs.time_step;} 76 | 77 | private: 78 | LifTracker2D(const size_t end_step) : iterator(){time_step = end_step;}; 79 | boost::array getTrackerDims() const; 80 | 81 | };*/ 82 | 83 | } 84 | #endif 85 | -------------------------------------------------------------------------------- /graphic/mains/aquireWisdom.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2008,2009 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | */ 19 | 20 | #include "../lifTracker.hpp" 21 | 22 | using namespace std; 23 | using namespace Colloids; 24 | 25 | #ifndef INSTAL_PATH 26 | #define INSTAL_PATH "c:/bin/" 27 | #endif 28 | 29 | int main(int argc, char* argv[]) 30 | { 31 | if(argc<2) 32 | { 33 | cout << "Syntax : aquireWisdom [path]filename" << endl; 34 | return EXIT_FAILURE; 35 | } 36 | string inputFile(argv[1]); 37 | try 38 | { 39 | LifReader reader(inputFile); 40 | const size_t serie = reader.chooseSerieNumber(); 41 | LifTracker track(reader.getSerie(serie),0, FFTW_EXHAUSTIVE); 42 | cout << "tracker ok"<. 18 | */ 19 | 20 | #include "../graphicParticles.hpp" 21 | 22 | using namespace std; 23 | using namespace cimg_library; 24 | 25 | /** 26 | \brief export the xy slices of a 3D image to tiff files. 27 | */ 28 | template 29 | void toTiff(const CImg &img, const string &outputPath) 30 | { 31 | ostringstream oss; 32 | oss << img.depth; 33 | const size_t nbZero = string(oss.str()).size(); 34 | cimg_for2Z(img,z) 35 | { 36 | ostringstream osz; 37 | osz << z; 38 | string zstr(osz.str()); 39 | for(size_t i = zstr.length();i img = Centers.getRepresentation((unsigned char)255,(unsigned char)0); 68 | if(argc>4) 69 | { 70 | float zblur; 71 | sscanf(argv[4],"%f",&zblur); 72 | img.blur(0,0,zblur); 73 | } 74 | if(argc>5) 75 | { 76 | float pNoise; 77 | sscanf(argv[5],"%f",&pNoise); 78 | if(argc>6) 79 | { 80 | sscanf(argv[6],"%u",&tNoise); 81 | img.noise(-pNoise,tNoise); 82 | } 83 | else img.noise(-pNoise); 84 | } 85 | 86 | img.display(); 87 | 88 | toTiff(img,outputPath); 89 | 90 | return EXIT_SUCCESS; 91 | } 92 | -------------------------------------------------------------------------------- /graphic/mains/lifTest.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2008,2009 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | */ 19 | #include "../lifFile.hpp" 20 | #include "CImg.h" 21 | 22 | using namespace std; 23 | using namespace cimg_library; 24 | using namespace Colloids; 25 | 26 | int main(int argc, char ** argv) 27 | { 28 | if(argc<2) 29 | { 30 | cout << "Syntax : liftest [path]filename" << endl; 31 | return EXIT_FAILURE; 32 | } 33 | 34 | const string filename(argv[1]); 35 | LifReader lif(filename); 36 | cout << "LIF version "<size()>3) 39 | do 40 | { 41 | cout<<"Chose a frame between 0 and "<at(3)->NumberOfElements-1<<": "; 42 | cin>>frame; 43 | } 44 | while(lif.Dimensions[serie]->at(3)->NumberOfElementsimg; 46 | switch (lif.Dimensions[serie]->size()) 47 | { 48 | case 0: 49 | cerr << "Serie "<at(0)->NumberOfElements); 54 | break; 55 | case 2: 56 | img.assign( 57 | lif.Dimensions[serie]->at(0)->NumberOfElements, 58 | lif.Dimensions[serie]->at(1)->NumberOfElements); 59 | break; 60 | default : 61 | img.assign( 62 | lif.Dimensions[serie]->at(0)->NumberOfElements, 63 | lif.Dimensions[serie]->at(1)->NumberOfElements, 64 | lif.Dimensions[serie]->at(2)->NumberOfElements); 65 | } 66 | cout<<"image constructed"<. 18 | 19 | * \file serieTracker.hpp 20 | * \brief Define a class to track series of 2D image files 21 | * \author Mathieu Leocmach 22 | * \date 11 January 2010 23 | * 24 | * 25 | */ 26 | #ifndef serie_tracker_H 27 | #define serie_tracker_file_H 28 | 29 | #include "tracker.hpp" 30 | #include 31 | namespace Colloids{ 32 | /** \brief glue between Tracker and image files 33 | Can be used as a stadard InputIterator 34 | */ 35 | class SerieTracker : public TrackerIterator 36 | { 37 | public: 38 | explicit SerieTracker( 39 | const std::string &namePattern, boost::array &xyzt, 40 | const double Zratio=1.0, 41 | const size_t ch=0, 42 | const unsigned fs=FFTW_ESTIMATE); 43 | SerieTracker end(){return SerieTracker(length);}; 44 | bool reachedEnd(){return getTimeStep()>=length;}; 45 | 46 | void setTimeStep(size_t t); 47 | double getZXratio(){return ZXratio;}; 48 | 49 | SerieTracker& operator++(); 50 | bool operator==(const SerieTracker& rhs) {return (getPattern()==rhs.getPattern()) && (time_step==rhs.time_step);} 51 | //bool operator!=(const SerieTracker& rhs) {return (getPattern()!=rhs.getPattern()) || (time_step!=rhs.time_step);} 52 | 53 | std::string getPattern() const {return namePattern;}; 54 | bool has_time() const {return hasTime;} 55 | bool has_depth() const {return hasDepth;} 56 | 57 | private: 58 | boost::format serie; 59 | size_t length; 60 | double ZXratio; 61 | bool hasTime, hasDepth; 62 | std::string namePattern; 63 | 64 | /** \brief default constructor that should be used only to get an "end" iterator*/ 65 | SerieTracker(const size_t end_step) {time_step = end_step;}; 66 | 67 | }; 68 | } 69 | #endif 70 | -------------------------------------------------------------------------------- /graphic/tinyxml/tinystr.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/graphic/tinyxml/tinystr.cpp -------------------------------------------------------------------------------- /graphic/tinyxml/tinyxmlerror.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | www.sourceforge.net/projects/tinyxml 3 | Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any 7 | damages arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any 10 | purpose, including commercial applications, and to alter it and 11 | redistribute it freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must 14 | not claim that you wrote the original software. If you use this 15 | software in a product, an acknowledgment in the product documentation 16 | would be appreciated but is not required. 17 | 18 | 2. Altered source versions must be plainly marked as such, and 19 | must not be misrepresented as being the original software. 20 | 21 | 3. This notice may not be removed or altered from any source 22 | distribution. 23 | */ 24 | 25 | #include "tinyxml.h" 26 | 27 | // The goal of the seperate error file is to make the first 28 | // step towards localization. tinyxml (currently) only supports 29 | // english error messages, but the could now be translated. 30 | // 31 | // It also cleans up the code a bit. 32 | // 33 | 34 | const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = 35 | { 36 | "No error", 37 | "Error", 38 | "Failed to open file", 39 | "Memory allocation failed.", 40 | "Error parsing Element.", 41 | "Failed to read Element name", 42 | "Error reading Element value.", 43 | "Error reading Attributes.", 44 | "Error: empty tag.", 45 | "Error reading end tag.", 46 | "Error parsing Unknown.", 47 | "Error parsing Comment.", 48 | "Error parsing Declaration.", 49 | "Error document empty.", 50 | "Error null (0) or unexpected EOF found in input stream.", 51 | "Error parsing CDATA.", 52 | "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.", 53 | }; 54 | -------------------------------------------------------------------------------- /lib/dynamicClusters.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2008,2009 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | 19 | * \file dynamicClusters.hpp 20 | * \brief Defines classes for time tracked clusters 21 | * \author Mathieu Leocmach 22 | * \version 0.1 23 | * \date 23 April 2009 24 | * 25 | */ 26 | 27 | #ifndef dynamic_clusters_H 28 | #define dynamic_clusters_H 29 | 30 | #include "dynamicParticles.hpp" 31 | namespace Colloids 32 | { 33 | 34 | void growCluster(std::set &population, std::set &cluster, size_t center, const NgbList &ngbs); 35 | void segregate(std::set &population, std::vector< std::set > &clusters, const NgbList &ngbs); 36 | void segregateAll(std::vector< std::set > &clusters, const Particles &parts); 37 | 38 | /** 39 | \brief Object representing clusters evolving in time 40 | */ 41 | class DynamicClusters 42 | { 43 | 44 | public: 45 | /** \brief The DynamicParticles of which the clusters are made of */ 46 | DynamicParticles *parts; 47 | 48 | /** 49 | \brief Clusters' members, time step by time step. 50 | The cluster given by members[t][i] is NOT (in general) the same cluster as members[t+1][i] 51 | */ 52 | std::deque< std::deque > > members; 53 | /** 54 | \brief The list of the clusters. 55 | The cluster given by members[t][trajectories[i][t]] IS the same cluster as members[t+1][trajectories[i][t+1]] 56 | */ 57 | TrajIndex trajectories; 58 | 59 | DynamicClusters(DynamicParticles &dynParts, std::set &population); 60 | 61 | DynamicClusters& assign(DynamicParticles &dynParts, std::set &population); 62 | 63 | void save(FileSerie &serie) const; 64 | 65 | ScalarDynamicField getLabels() const; 66 | 67 | BoundingBox bounds(const std::set &cluster,const size_t &time); 68 | 69 | std::valarray getLargestDelta(const size_t &time); 70 | }; 71 | }; 72 | #endif 73 | -------------------------------------------------------------------------------- /lib/fields.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2010 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | 19 | 20 | * \file fields.cpp 21 | * \brief Implement classes to manage fields of values : scalar, vectorial, static or dynamic 22 | * \author Mathieu Leocmach 23 | * \date 3 February 2010 24 | * 25 | */ 26 | 27 | #include "fields.hpp" 28 | 29 | using namespace std; 30 | using namespace Colloids; 31 | 32 | /** @brief write as vtk legacy format */ 33 | ostream & Colloids::operator<<(std::ostream &os, const ScalarField &s) 34 | { 35 | os<<"SCALARS "<< s.name<<" double\n" 36 | "LOOKUP_TABLE default\n"; 37 | copy( 38 | s.values.begin(), s.values.end(), 39 | ostream_iterator(os,"\n") 40 | ); 41 | return os; 42 | } 43 | 44 | /** @brief write as vtk legacy format */ 45 | ostream & Colloids::operator<<(std::ostream &os, const VectorField &v) 46 | { 47 | os<<"VECTORS "<. 18 | **/ 19 | 20 | #include "files_series.hpp" 21 | #include 22 | 23 | using namespace std; 24 | using namespace Colloids; 25 | 26 | /** @brief Constructor */ 27 | FileSerie::FileSerie(const std::string &namePattern, const std::string &token, size_t size, size_t offset) : 28 | token(token), length(size), offset(offset) 29 | { 30 | string head = namePattern, tail; 31 | size_t digits=0, pos = namePattern.rfind(token); 32 | 33 | if(pos==string::npos) 34 | throw invalid_argument(("Name pattern \""+namePattern+"\" doesn't contain token \""+token+"\"").c_str()); 35 | 36 | head.resize(pos); 37 | digits = namePattern.find_first_not_of("0123456789", pos+token.size()); 38 | tail = namePattern.substr(digits); 39 | digits -= pos+token.size(); 40 | 41 | ostringstream os; 42 | os<pattern.parse(os.str()); 46 | } 47 | catch(exception &e) 48 | { 49 | cerr<<"head: "<pattern; 61 | fmt.clear(); 62 | string pat = (fmt % 0).str(); 63 | pat = pat.substr(0, pat.rfind(".")) + ext; 64 | return FileSerie(pat, this->token, this->size(), this->offset); 65 | } 66 | 67 | /** @brief return a new FileSerie with a postfix added just before the token */ 68 | FileSerie FileSerie::addPostfix(const std::string &postfix) const 69 | { 70 | boost::format fmt = this->pattern; 71 | fmt.clear(); 72 | string pat = (fmt % 0).str(); 73 | pat.insert(pat.rfind(this->token), postfix); 74 | return FileSerie(pat, this->token, this->size(), this->offset); 75 | } 76 | 77 | /** @brief return a new FileSerie with a postfix added just before the token and a different extension */ 78 | FileSerie FileSerie::addPostfix(const std::string &postfix, const std::string &ext) const 79 | { 80 | boost::format fmt = this->pattern; 81 | fmt.clear(); 82 | string pat = (fmt % 0).str(); 83 | pat.insert(pat.rfind(this->token), postfix); 84 | pat = pat.substr(0, pat.rfind(".")) + ext; 85 | return FileSerie(pat, this->token, this->size(), this->offset); 86 | } 87 | 88 | /** @brief return the head of the serie, without time dependence, with the given extension */ 89 | string FileSerie::head() const 90 | { 91 | boost::format fmt = this->pattern; 92 | fmt.clear(); 93 | string pat = (fmt % 0).str(); 94 | pat.erase(pat.rfind(this->token)); 95 | return pat; 96 | } 97 | 98 | /** @brief get the 0th file (no extention) for a given prefix and a given serie size */ 99 | string FileSerie::get0th(const std::string &prefix, const size_t &size, const std::string &token) 100 | { 101 | ostringstream nbframes; 102 | nbframes << size-1; 103 | const size_t digits = std::max(nbframes.str().size(), (size_t)1); 104 | ostringstream os; 105 | os<. 18 | 19 | 20 | * \file files_series.hpp 21 | * \brief Defines classes for time series and z series of files 22 | * \author Mathieu Leocmach 23 | * \version 0.1 24 | * \date 15 December 2008 25 | * 26 | * Define functions and classes relative to the files series for the particle tracking code 27 | * 28 | */ 29 | 30 | #ifndef file_series_H 31 | #define file_series_H 32 | 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | namespace Colloids 42 | { 43 | class FileSerie 44 | { 45 | boost::format pattern; 46 | std::string token; 47 | size_t length, offset; 48 | 49 | public: 50 | FileSerie(const std::string &filesPattern, const std::string &token, size_t size, size_t offset=0); 51 | std::string operator%(const size_t &step){this->pattern.clear(); return (pattern%(step+offset)).str();} 52 | size_t size() const {return length;} 53 | size_t get_offset() const {return offset;} 54 | FileSerie changeExt(const std::string &ext) const; 55 | FileSerie addPostfix(const std::string &postfix) const; 56 | FileSerie addPostfix(const std::string &postfix, const std::string &ext) const; 57 | std::string head() const; 58 | 59 | static std::string get0th(const std::string &prefix, const size_t &size, const std::string &token="_t"); 60 | }; 61 | } 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /lib/index.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2008,2009 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | 19 | */ 20 | 21 | #include "index.hpp" 22 | using namespace std; 23 | using namespace Colloids; 24 | 25 | /** @brief Get the indices of the objects contained inside a reduction of the maximum bounding box */ 26 | vector SpatialIndex::getInside(const double &margin, const bool noZ) const 27 | { 28 | BoundingBox insideBox = getOverallBox(); 29 | for(size_t i=0;i<3-noZ;++i) 30 | if(insideBox.edges[i].second-insideBox.edges[i].first>2*margin) 31 | { 32 | insideBox.edges[i].first += margin; 33 | insideBox.edges[i].second -= margin; 34 | } 35 | //gets the indexes of the particles totally contained inside this volume 36 | return (*this)(insideBox); 37 | } 38 | 39 | /** @brief Get objects spanning the whole interval inside the query box */ 40 | vector SpatioTemporalIndex::operator()(const BoundingBox &b) const 41 | { 42 | return (*this)(TimeBox(getOverallInterval(),b)); 43 | } 44 | 45 | /** @brief Get all the objects spanning the query interval */ 46 | vector SpatioTemporalIndex::operator()(const Interval &in) const 47 | { 48 | return (*this)(TimeBox(in,getOverallBox())); 49 | } 50 | 51 | /** @brief Get the indices of the objects spanning the query interval inside a reduction of the maximum bounding box */ 52 | vector SpatioTemporalIndex::getSpanningInside(const Interval &in,const double &margin) const 53 | { 54 | BoundingBox insideBox = getOverallBox(); 55 | for(size_t i=0;i<3;++i) 56 | if(insideBox.edges[i].second-insideBox.edges[i].first>2*margin) 57 | { 58 | insideBox.edges[i].first += margin; 59 | insideBox.edges[i].second -= margin; 60 | } 61 | //gets the indexes of the particles totally contained inside this volume 62 | return (*this)(TimeBox(in,insideBox)); 63 | } 64 | 65 | /** @brief Get the indices of the objects spanning the whole interval inside a reduction of the maximum bounding box 66 | */ 67 | vector SpatioTemporalIndex::getInside(const double &margin) const 68 | { 69 | return getSpanningInside(getOverallInterval(),margin); 70 | } 71 | 72 | 73 | 74 | /** @brief insert */ 75 | void BruteSpatialIndex::insert(const size_t &i, const BoundingBox &b) 76 | { 77 | if(!overallBox) 78 | overallBox = new BoundingBox(b); 79 | else 80 | overallBox->stretch(b); 81 | items.insert(make_pair(i,b)); 82 | } 83 | 84 | /** @brief get all items included in the query box 85 | complexity ~N 86 | */ 87 | vector BruteSpatialIndex::operator()(const BoundingBox &b) const 88 | { 89 | list ret; 90 | for(multimap::const_iterator it = items.begin(); it!= items.end();++it) 91 | if(b.encloses(it->second)) 92 | ret.push_back(it->first); 93 | ret.sort(); 94 | ret.unique(); 95 | return vector(ret.begin(), ret.end()); 96 | } 97 | 98 | /** @brief Translate all bounding boxes */ 99 | void BruteSpatialIndex::operator+=(const Coord &v) 100 | { 101 | for(multimap::iterator it = items.begin(); it!= items.end();++it) 102 | it->second += v; 103 | } 104 | 105 | void RStarIndex_S::insert(const size_t &i, const BoundingBox &b) 106 | { 107 | tree.Insert(i,b); 108 | } 109 | 110 | /** @brief Get the indices of the objects whose bounding boxes are contained inside the query box */ 111 | vector RStarIndex_S::operator()(const BoundingBox &b) const 112 | { 113 | list g = tree.Query(RTree::AcceptEnclosing(b), Gatherer()).gathered; 114 | g.sort(); 115 | g.unique(); 116 | return vector(g.begin(), g.end()); 117 | } 118 | 119 | /** @brief insertion */ 120 | void TreeIndex_T::insert(const size_t &i, const Interval &in) 121 | { 122 | if(!overallInterval) 123 | overallInterval = new Interval(in); 124 | else 125 | { 126 | overallInterval->first = min(overallInterval->first, in.first); 127 | overallInterval->second = max(overallInterval->second, in.second); 128 | } 129 | for(size_t t = tree.size();t<=in.first;++t) 130 | tree.push_back(new boost::ptr_vector< std::set >); 131 | for(size_t t = tree[in.first].size();t<=in.second-in.first;++t) 132 | tree[in.first].push_back(new std::set); 133 | tree[in.first][in.second-in.first].insert(tree[in.first][in.second-in.first].end(),i); 134 | } 135 | 136 | /** @brief Get the objects spanning at least the query interval */ 137 | vector TreeIndex_T::operator()(const Interval &in) const 138 | { 139 | list sel; 140 | for(size_t t0=0;t0<=min(in.first,tree.size());++t0) 141 | for(size_t t1=in.second-in.first;t1(sel.begin(), sel.end()); 146 | } 147 | 148 | -------------------------------------------------------------------------------- /lib/periodic.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2008,2009 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | **/ 19 | 20 | #include "periodic.hpp" 21 | 22 | using namespace std; 23 | using namespace Colloids; 24 | 25 | /** \brief Transform a vector for it to be in the boundary conditions */ 26 | void PeriodicParticles::periodify(Coord &v) const 27 | { 28 | for(size_t i=0;i<3;++i) 29 | { 30 | if(v[i]>getPeriod(i)/2.0) v[i] -= getPeriod(i); 31 | if(v[i]<=-getPeriod(i)/2.0) v[i] += getPeriod(i); 32 | } 33 | } 34 | 35 | 36 | /** \brief get the difference vector between a position and one of the particles */ 37 | Coord PeriodicParticles::getDiff(const Coord &from,const size_t &to) const 38 | { 39 | Coord diff(3); 40 | diff = Particles::getDiff(from,to); 41 | periodify(diff); 42 | return diff; 43 | } 44 | /** \brief get the difference vector between two particles */ 45 | Coord PeriodicParticles::getDiff(const size_t &from,const size_t &to) const 46 | { 47 | Coord diff(3); 48 | diff = Particles::getDiff(from,to); 49 | periodify(diff); 50 | return diff; 51 | } 52 | 53 | /** \brief return the number density without margin */ 54 | double PeriodicParticles::getNumberDensity() const 55 | { 56 | return size()/bb.area(); 57 | } 58 | 59 | /** 60 | \brief get the index of the particle contained inside a reduction of the bounding box. 61 | \param cutoff range to exclude from each side of the box 62 | \return list of all the particles 63 | Dummy function in the case of periodic boundary condition. 64 | */ 65 | vector PeriodicParticles::selectInside(const double &margin, const bool noZ) const 66 | { 67 | vector inside(size()); 68 | for(size_t i=0;i PeriodicParticles::selectEnclosed(const BoundingBox &b) const 79 | { 80 | //case where the query doesn't get across the boundaries 81 | if(bb.encloses(b)) 82 | return Particles::selectEnclosed(b); 83 | 84 | // case where the periodicity has to be taken into account 85 | BoundingBox queryBox = b; 86 | valarray translation(0.0,3); 87 | listtotal; 88 | vectornewParts; 89 | for(int i=-1;i<=1;++i) 90 | { 91 | translation[0]=i*getPeriod(0); 92 | for(int j=-1;j<=1;++j) 93 | { 94 | translation[1]=j*getPeriod(1); 95 | for(int k=-1;k<=1;++k) 96 | { 97 | translation[2]=k*getPeriod(2); 98 | //the query box get translated to an other side of the periodic boundaries 99 | for(size_t d=0;d<3;++d) 100 | { 101 | queryBox.edges[d].first=b.edges[d].first+translation[d]; 102 | queryBox.edges[d].second=b.edges[d].second+translation[d]; 103 | } 104 | //if ever the box contains no particle, the query on the R*Tree return an empty result in constant time (immediately) 105 | //so no special precaution to discard in advance irrealistic translations of the query box. 106 | newParts = Particles::selectEnclosed(queryBox); 107 | //the new set of particles is added 108 | copy(newParts.begin(),newParts.end(), back_inserter(total)); 109 | } 110 | } 111 | } 112 | total.sort(); 113 | total.unique(); 114 | return vector(total.begin(), total.end()); 115 | 116 | } 117 | -------------------------------------------------------------------------------- /lib/periodic.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2008,2009 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | 19 | 20 | * \file periodic.hpp 21 | * \brief Defines classes for particles spatially indexed with periodic boundary conditions 22 | * \author Mathieu Leocmach 23 | * \version 0.1 24 | * \date 29 January 2009 25 | * 26 | */ 27 | 28 | #ifndef periodic_particles_H 29 | #define periodic_particles_H 30 | 31 | #include "particles.hpp" 32 | 33 | namespace Colloids 34 | { 35 | /** \brief indexed particles with periodic boundary conditions */ 36 | class PeriodicParticles : public Particles 37 | { 38 | public: 39 | 40 | PeriodicParticles(const double &rad) : Particles(0, rad){return;}; 41 | PeriodicParticles(const std::vector &input,const double &rad) : Particles(input,rad){return;}; 42 | PeriodicParticles(const Particles &input) : Particles(input){return;}; 43 | PeriodicParticles(const std::string &filename,const double &rad) : Particles(filename,rad){return;}; 44 | PeriodicParticles(const size_t &Nb, const BoundingBox &b, const std::string &filename, const double &rad) : Particles(Nb,b,filename,rad){return;}; 45 | 46 | inline double getPeriod(const size_t &d) const; 47 | 48 | void periodify(Coord &v) const; 49 | Coord getDiff(const Coord &from,const size_t &to) const; 50 | Coord getDiff(const size_t &from,const size_t &to) const; 51 | double getNumberDensity() const; 52 | std::vector selectInside(const double &margin, const bool noZ=false) const; 53 | std::vector selectEnclosed(const BoundingBox &b) const; 54 | std::vector selectInside_noindex(const double &margin, const bool noZ=false) const{return this->selectInside(margin, noZ);}; 55 | //vector getEuclidianNeighbours(const valarray ¢er, const double &range) const; 56 | }; 57 | 58 | /** \brief get the periodicity according to the bounding box */ 59 | inline double PeriodicParticles::getPeriod(const size_t &d) const 60 | { 61 | return bb.edges[d].second-bb.edges[d].first; 62 | } 63 | }; 64 | #endif 65 | -------------------------------------------------------------------------------- /liveTrack/FFT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace cimg_library; 3 | 4 | int main(int argc, char* argv[]) { 5 | const CImg img = CImg(argv[1]).channel(1); 6 | CImgList<> F = img.get_FFT(); 7 | cimglist_apply(F,translate)(img.dimx()/2,img.dimy()/2,0,0,2); 8 | const CImg mag = ((F[0].get_pow(2) + F[1].get_pow(2)).sqrt()+1.0f).log().normalize(0,255); 9 | CImgList visu(img,mag); 10 | CImgDisplay disp(visu,"[#16] - Fourier Filtering (Click to set filter)"); 11 | CImg mask(img.dimx(),img.dimy(),1,1,1); 12 | unsigned char one[] = { 1 }, zero[] = { 0 }, white[] = { 255 }; 13 | int rmin = 0, rmax = 256; 14 | while (!disp.is_closed && !disp.is_keyQ && !disp.is_keyESC) { 15 | disp.wait(); 16 | const int 17 | xm = disp.mouse_x*2*img.dimx()/disp.dimx()-img.dimx(), 18 | ym = disp.mouse_y*img.dimy()/disp.dimy(), 19 | x = xm-img.dimx()/2, 20 | y = ym-img.dimy()/2; 21 | if (disp.button && xm>=0 && ym>=0) { 22 | const int r = (int)cimg::max(0.0f,(float)std::sqrt((float)x*x+y*y)-3.0f); 23 | if (disp.button&1) rmax = r; 24 | if (disp.button&2) rmin = r; 25 | if (rmin>=rmax) rmin = cimg::max(rmax-1,0); 26 | mask.fill(0).draw_circle(mag.dimx()/2,mag.dimy()/2,rmax,one). 27 | draw_circle(mag.dimx()/2,mag.dimy()/2,rmin,zero); 28 | CImgList<> nF(F); 29 | cimglist_for(F,l) nF[l].mul(mask).translate(-img.dimx()/2,-img.dimy()/2,0,0,2); 30 | visu[0] = nF.FFT(true)[0].normalize(0,255); 31 | } 32 | if (disp.is_resized) disp.resize(disp.window_dimx(),disp.window_dimx()/2).display(visu); 33 | visu[1] = mag.get_mul(mask).draw_text(5,5,white,zero,11,0.6f,"Freq Min/Max = %d / %d",(int)rmin,(int)rmax); 34 | visu.display(disp); 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /liveTrack/liveTrack2D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace cimg_library; 4 | 5 | int main(int argc, char* argv[]) { 6 | const CImg img = CImg(argv[1]).channel(1).normalize(0,255); 7 | CImgList<> F = img.get_FFT(); 8 | cimglist_apply(F,translate)(img.dimx()/2,img.dimy()/2,0,0,2); 9 | const CImg mag = ((F[0].get_pow(2) + F[1].get_pow(2)).sqrt()+1.0f).log().normalize(0,255); 10 | CImg tracked(img.dimx(),img.dimy(),img.dimz(),2,0); 11 | tracked.get_shared_channel(0)=img; 12 | CImg treated(tracked); 13 | CImgList visu(treated,mag,tracked); 14 | CImgDisplay disp(visu,"Fourier Filtering (Click on the middle image to set filter)"); 15 | CImg hist(256,65,1,1,0); 16 | CImgDisplay histo(hist, "Histogram (Clic to set threshold)"); 17 | CImg mask(img.dimx(),img.dimy(),1,1,1),thr_mask(mask); 18 | unsigned char one[] = { 1 }, zero[] = { 0 }, white[] = { 255 },grey[]={127}; 19 | int fminx = 0, fmaxx = img.dimx(),fminy = 0, fmaxy = img.dimy(); 20 | unsigned char thr=0; 21 | hist.draw_graph(img.get_histogram(),white).display(histo); 22 | while (!disp.is_closed && !disp.is_keyQ && !disp.is_keyESC) { 23 | disp.wait_all(); 24 | const int 25 | xm = disp.mouse_x*3*img.dimx()/disp.dimx()-img.dimx(), 26 | ym = disp.mouse_y*img.dimy()/disp.dimy(), 27 | x = xm-img.dimx()/2, 28 | y = ym-img.dimy()/2; 29 | //histo.wait(); 30 | const int xh = histo.mouse_x*hist.dimx()/histo.dimx(); 31 | //std::cout << xh <=0 && xh<256) 33 | { 34 | thr=xh; 35 | } 36 | if (disp.button && xm>=0 && ym>=0 && xm=fmaxx) fminx = cimg::max(fmaxx-1,0); 57 | if (fminy>=fmaxy) fminy = cimg::max(fmaxy-1,0); 58 | mask.fill(0).draw_ellipse(mag.dimx()/2,mag.dimy()/2,(float)fmaxx,(float)fmaxy,0,0,one). 59 | draw_ellipse(mag.dimx()/2,mag.dimy()/2,(float)fminx,(float)fminy,0,0,zero); 60 | CImgList<> nF(F); 61 | cimglist_for(F,l) nF[l].mul(mask).translate(-img.dimx()/2,-img.dimy()/2,0,0,2); 62 | visu[0].get_shared_channel(0) = nF.FFT(true)[0].normalize(0,255); 63 | } 64 | if (disp.is_resized) disp.resize(disp.window_dimx(),disp.window_dimx()/2).display(visu); 65 | visu[1] = mag.get_mul(mask).draw_text(5,5,white,zero,11,0.6f,"Radiusx Min/Max = %f / %f\nRadiusy Min/Max = %f / %f",((float)img.dimx())/((float)fmaxx)/2.0,((float)img.dimx())/((float)fminx)/2.0,((float)img.dimy())/((float)fmaxy)/2.0,((float)img.dimx())/((float)fminy)/2.0); 66 | hist.fill(0).draw_rectangle(0,0,thr,64,grey).draw_graph(visu[0].get_shared_channel(0).get_histogram(),white).draw_text(5,5,white,zero,11,0.6f,"Thr = %u",thr); 67 | visu[0].get_shared_channel(1) = 128*(1-visu[0].get_shared_channel(0).get_threshold(thr)); 68 | visu[2].get_shared_channel(1) = (visu[0].get_shared_channel(0)-visu[0].get_shared_channel(0).get_dilate(3)).exp().threshold(0.9999).mul(visu[0].get_shared_channel(0).get_threshold(thr))*255; 69 | visu.display(disp); 70 | hist.display(histo); 71 | } 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /m4/ltsugar.m4: -------------------------------------------------------------------------------- 1 | # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- 2 | # 3 | # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. 4 | # Written by Gary V. Vaughan, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # serial 6 ltsugar.m4 11 | 12 | # This is to help aclocal find these macros, as it can't see m4_define. 13 | AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) 14 | 15 | 16 | # lt_join(SEP, ARG1, [ARG2...]) 17 | # ----------------------------- 18 | # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their 19 | # associated separator. 20 | # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier 21 | # versions in m4sugar had bugs. 22 | m4_define([lt_join], 23 | [m4_if([$#], [1], [], 24 | [$#], [2], [[$2]], 25 | [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) 26 | m4_define([_lt_join], 27 | [m4_if([$#$2], [2], [], 28 | [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) 29 | 30 | 31 | # lt_car(LIST) 32 | # lt_cdr(LIST) 33 | # ------------ 34 | # Manipulate m4 lists. 35 | # These macros are necessary as long as will still need to support 36 | # Autoconf-2.59 which quotes differently. 37 | m4_define([lt_car], [[$1]]) 38 | m4_define([lt_cdr], 39 | [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], 40 | [$#], 1, [], 41 | [m4_dquote(m4_shift($@))])]) 42 | m4_define([lt_unquote], $1) 43 | 44 | 45 | # lt_append(MACRO-NAME, STRING, [SEPARATOR]) 46 | # ------------------------------------------ 47 | # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. 48 | # Note that neither SEPARATOR nor STRING are expanded; they are appended 49 | # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). 50 | # No SEPARATOR is output if MACRO-NAME was previously undefined (different 51 | # than defined and empty). 52 | # 53 | # This macro is needed until we can rely on Autoconf 2.62, since earlier 54 | # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. 55 | m4_define([lt_append], 56 | [m4_define([$1], 57 | m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) 58 | 59 | 60 | 61 | # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) 62 | # ---------------------------------------------------------- 63 | # Produce a SEP delimited list of all paired combinations of elements of 64 | # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list 65 | # has the form PREFIXmINFIXSUFFIXn. 66 | # Needed until we can rely on m4_combine added in Autoconf 2.62. 67 | m4_define([lt_combine], 68 | [m4_if(m4_eval([$# > 3]), [1], 69 | [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl 70 | [[m4_foreach([_Lt_prefix], [$2], 71 | [m4_foreach([_Lt_suffix], 72 | ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, 73 | [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) 74 | 75 | 76 | # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) 77 | # ----------------------------------------------------------------------- 78 | # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited 79 | # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. 80 | m4_define([lt_if_append_uniq], 81 | [m4_ifdef([$1], 82 | [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], 83 | [lt_append([$1], [$2], [$3])$4], 84 | [$5])], 85 | [lt_append([$1], [$2], [$3])$4])]) 86 | 87 | 88 | # lt_dict_add(DICT, KEY, VALUE) 89 | # ----------------------------- 90 | m4_define([lt_dict_add], 91 | [m4_define([$1($2)], [$3])]) 92 | 93 | 94 | # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) 95 | # -------------------------------------------- 96 | m4_define([lt_dict_add_subkey], 97 | [m4_define([$1($2:$3)], [$4])]) 98 | 99 | 100 | # lt_dict_fetch(DICT, KEY, [SUBKEY]) 101 | # ---------------------------------- 102 | m4_define([lt_dict_fetch], 103 | [m4_ifval([$3], 104 | m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), 105 | m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) 106 | 107 | 108 | # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) 109 | # ----------------------------------------------------------------- 110 | m4_define([lt_if_dict_fetch], 111 | [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], 112 | [$5], 113 | [$6])]) 114 | 115 | 116 | # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) 117 | # -------------------------------------------------------------- 118 | m4_define([lt_dict_filter], 119 | [m4_if([$5], [], [], 120 | [lt_join(m4_quote(m4_default([$4], [[, ]])), 121 | lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), 122 | [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl 123 | ]) 124 | -------------------------------------------------------------------------------- /m4/ltversion.m4: -------------------------------------------------------------------------------- 1 | # ltversion.m4 -- version numbers -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # @configure_input@ 11 | 12 | # serial 3294 ltversion.m4 13 | # This file is part of GNU Libtool 14 | 15 | m4_define([LT_PACKAGE_VERSION], [2.4]) 16 | m4_define([LT_PACKAGE_REVISION], [1.3294]) 17 | 18 | AC_DEFUN([LTVERSION_VERSION], 19 | [macro_version='2.4' 20 | macro_revision='1.3294' 21 | _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) 22 | _LT_DECL(, macro_revision, 0) 23 | ]) 24 | -------------------------------------------------------------------------------- /mains/ISF.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2008,2009 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | **/ 19 | #include 20 | #include "dynamicParticles.hpp" 21 | 22 | 23 | using namespace std; 24 | using namespace Colloids; 25 | 26 | int main(int argc, char ** argv) 27 | { 28 | if(argc<4) 29 | { 30 | cout << "compute Self Intermediate scattering function for sub-time intervals"< ISF; 45 | boost::format name (inputPath+"_%1%from_%2%to_%3%av.isf"); 46 | for(size_t i=0;iparts.getNbTimeSteps() || stop+av+1>parts.getNbTimeSteps()) 52 | throw invalid_argument 53 | ( 54 | (boost::format("[%1%,%2%] not included in [0,%3%]") % start % (stop+av) % (parts.getNbTimeSteps()-1)).str() 55 | ); 56 | cout<<"["<" << endl; 57 | ISF = parts.getSelfISF(start,stop,av); 58 | 59 | //export to file 60 | ofstream output((name % start %stop %av).str().c_str(), std::ios::out | std::ios::trunc); 61 | output <<"#t\tISF"< MSD; 24 | boost::format name (inputPath+"_%1%from_%2%to_%3%av.msd"); 25 | for(size_t i=0;iparts.getNbTimeSteps() || stop+av+1>parts.getNbTimeSteps()) 31 | throw invalid_argument 32 | ( 33 | (boost::format("[%1%,%2%] not included in [0,%3%]") % start % (stop+av) % (parts.getNbTimeSteps()-1)).str() 34 | ); 35 | cout<<"["<" << endl; 36 | MSD = parts.getMSD(start,stop,av); 37 | 38 | //export to file 39 | ofstream output((name % start %stop %av).str().c_str(), std::ios::out | std::ios::trunc); 40 | output <<"#t\tMSD"<. 18 | **/ 19 | 20 | #include "dynamicParticles.hpp" 21 | #include 22 | 23 | using namespace std; 24 | using namespace Colloids; 25 | 26 | int main(int argc, char ** argv) 27 | { 28 | try 29 | { 30 | if(argc<2) 31 | { 32 | cerr<<"syntax: all_bonds [path]filename.traj"<> radius >> delta_t; 50 | trajfile.ignore(1); //escape the endl 51 | getline(trajfile, pattern); //pattern is on the 2nd line 52 | getline(trajfile, token); //token is on the 3rd line 53 | trajfile >> offset >> span; 54 | pattern.insert(0, path); 55 | 56 | 57 | cout< positions(span); 67 | for(size_t t=0; t total_g(200, 0.0); 81 | { 82 | ifstream in((datSerie.head()+".rdf").c_str()); 83 | if(in.good()) 84 | { 85 | cout<<"load "<> total_g[r] >> total_g[r]; 90 | } 91 | else 92 | { 93 | cout<<"calculate rdf and save it to "< g = positions[t].getRdf(200,15.0); 100 | for(int r=0; r<(int)g.size(); ++r) 101 | total_g[r] += g[r]; 102 | ++show_pr; 103 | } 104 | ofstream rdfFile((datSerie.head()+".rdf").c_str(), ios::out | ios::trunc); 105 | rdfFile << "#r\tg(r)"<::iterator first_peak = total_g.begin(); 114 | size_t first_min; 115 | do 116 | { 117 | first_peak = max_element(total_g.begin(),total_g.end()); 118 | first_min = distance(total_g.begin(), min_element(first_peak,total_g.end())); 119 | //cout<<"first_peak="< inside, secondInside; 137 | //create neighbour list and export bonds 138 | positions[t].makeNgbList(bondLength); 139 | bonds = positions[t].getBonds(); 140 | ofstream bondFile((bondSerie%t).c_str(), ios::out | ios::trunc); 141 | copy(bonds.begin(), bonds.end(), ostream_iterator(bondFile, "\n")); 142 | bondFile.close(); 143 | 144 | //remove neigbour list from memory (can be heavy) 145 | positions[t].delNgbList(); 146 | ++(*show_progress); 147 | 148 | } 149 | } 150 | } 151 | catch(const exception &e) 152 | { 153 | cerr<< e.what()<. 18 | **/ 19 | 20 | #include "dynamicParticles.hpp" 21 | 22 | #include 23 | 24 | using namespace std; 25 | using namespace Colloids; 26 | 27 | int main(int argc, char ** argv) 28 | { 29 | if(argc<3) 30 | { 31 | cout << "Average the positions over time"<> radius >> dt; 56 | trajfile.ignore(1); //escape the endl 57 | getline(trajfile, pattern); //pattern is on the 2nd line 58 | getline(trajfile, token); //token is on the 3rd line 59 | trajfile >> offset >> size; 60 | trajfile.close(); 61 | } 62 | //File series 63 | FileSerie datSerie(path+os.str()+pattern, token, size, offset); 64 | cout<<"load"<. 18 | **/ 19 | 20 | //Define the preprocessor variable "periodic" if you want periodic boundary conditions 21 | #include "periodic.hpp" 22 | 23 | using namespace std; 24 | using namespace Colloids; 25 | 26 | int main(int argc, char ** argv) 27 | { 28 | try 29 | { 30 | if(argc<2) throw invalid_argument("Syntax : coordinateFile [maxBondLength]"); 31 | 32 | const string filename(argv[1]); 33 | const string inputPath = filename.substr(0,filename.find_last_of(".")); 34 | const string ext = filename.substr(filename.find_last_of(".")+1); 35 | double maxBondLength = 0.0; 36 | BondSet bonds; 37 | Particles parts(filename,1); 38 | parts.makeRTreeIndex(); 39 | if(argc>2) 40 | maxBondLength = atof(argv[2]); 41 | else 42 | { 43 | vector g = parts.getRdf(200,15.0); 44 | //set the max bond length as the first minima of g(r) 45 | //the loop is here only to get rid of possible multiple centers at small r 46 | vector::iterator first_peak = g.begin(); 47 | size_t first_min; 48 | do 49 | { 50 | first_peak = max_element(g.begin(),g.end()); 51 | first_min = distance(g.begin(), min_element(first_peak,g.end())); 52 | } 53 | while(g[first_min]==0.0); 54 | } 55 | parts.makeNgbList(maxBondLength); 56 | bonds = parts.getBonds(); 57 | ofstream output((inputPath + ".bonds").c_str(), ios::out | ios::trunc); 58 | for(BondSet::const_iterator b=bonds.begin(); b!= bonds.end();++b) 59 | output<low()<<" "<high()<<"\n"; 60 | } 61 | catch(const exception &e) 62 | { 63 | cerr<< e.what()< boof,Sboof; 25 | map::iterator booit; 26 | set inside = parts.getRealInside(1.4*2.0*radius); 27 | for(set::iterator p=inside.begin();p!=inside.end();++p) 28 | { 29 | set EuNgb = parts.getEuclidianNeighbours(parts[*p],1.4*2.0*radius); 30 | if(EuNgb.size()>1) 31 | { 32 | booit = boof.insert(boof.end(),make_pair(*p,boo_five())); 33 | for(set::iterator n=EuNgb.begin();n!=EuNgb.end();++n) 34 | if( *p != *n) 35 | booit->second += boo_five(parts.getDiff(*p,*n)); 36 | booit->second /= (double)(EuNgb.size()-1); 37 | } 38 | } 39 | 40 | //coarse grained 41 | set second_inside = parts.getRealInside(2.0*1.4*2.0*radius); 42 | map::const_iterator bofit; 43 | for(set::iterator p=second_inside.begin();p!=second_inside.end();++p) 44 | { 45 | set EuNgb = parts.getEuclidianNeighbours(parts[*p],1.4*2.0*radius); 46 | booit = Sboof.insert(Sboof.end(),make_pair(*p,boo_five())); 47 | for(set::iterator n=EuNgb.begin();n!=EuNgb.end();++n) 48 | { 49 | bofit=boof.find(*p); 50 | if(bofit!=boof.end()); 51 | booit->second += (*bofit).second; 52 | } 53 | } 54 | 55 | vector q5(2); 56 | q5[0].first = new string("q5"); 57 | q5[1].first = new string("Sq5"); 58 | q5[0].second = new map(); 59 | q5[1].second = new map(); 60 | for(bofit=boof.begin();bofit!=boof.end();++bofit) 61 | q5[0].second->insert(q5[0].second->end(),make_pair(bofit->first,bofit->second.getQ5())); 62 | for(bofit=Sboof.begin();bofit!=Sboof.end();++bofit) 63 | q5[1].second->insert(q5[1].second->end(),make_pair(bofit->first,bofit->second.getQ5())); 64 | 65 | parts.exportToVTK(inputPath+"_five.vtk",q5); 66 | } 67 | catch(const exception &e) 68 | { 69 | cerr<< e.what()<. 18 | **/ 19 | 20 | #include "particles.hpp" 21 | #include "files_series.hpp" 22 | #include 23 | #include 24 | 25 | namespace po = boost::program_options; 26 | using namespace std; 27 | using namespace Colloids; 28 | 29 | int main(int argc, char ** argv) 30 | { 31 | try 32 | { 33 | string filename, token, outputPostfix; 34 | double minSep; 35 | size_t t_offset; 36 | po::options_description 37 | compulsory_options("Compulsory options"), 38 | additional_options("Additional options"), 39 | cmdline_options("Command-line options"); 40 | compulsory_options.add_options() 41 | ("input", po::value(&filename), "input file or pattern") 42 | ("minSep", po::value(&minSep), "Minimum separation between particles (in pixels)") 43 | ; 44 | po::positional_options_description pd; 45 | pd.add("input", 1); 46 | pd.add("minSep", 2); 47 | additional_options.add_options() 48 | ("help", "produce help message") 49 | ("token", po::value(&token)->default_value("_t"), "Token delimiting time step number (for time series only)") 50 | ("span", po::value(), "Number of time steps to process (compulsory for time series)") 51 | ("offset", po::value(&t_offset)->default_value(0), "Starting time step") 52 | ("both", "Removes both particles if they are closer than minSep (removes only the second one by default, ie the dimmer one)") 53 | ("outputPostfix,o", po::value(&outputPostfix)->default_value(""), "If empty output prefix is given, overwrites the files.") 54 | ; 55 | 56 | cmdline_options.add(compulsory_options).add(additional_options); 57 | 58 | po::variables_map vm; 59 | po::store(po::command_line_parser(argc, argv). 60 | options(cmdline_options).positional(pd).run(), vm); 61 | 62 | if (vm.count("help") || (!vm.count("input") && !vm.count("minSep"))) 63 | { 64 | cout << "cutter input minSep [options]\n"; 65 | cout << cmdline_options << "\n"; 66 | return EXIT_SUCCESS; 67 | } 68 | po::notify(vm); 69 | 70 | const string inputPath = filename.substr(0,filename.find_last_of(".")); 71 | const string ext = filename.substr(filename.find_last_of(".")+1); 72 | 73 | if(vm.count("span")) 74 | { 75 | cout<<"file serie"<(), t_offset), 77 | outSerie = datSerie.addPostfix(outputPostfix, ".dat"); 78 | boost::progress_display show_progress(vm["span"].as()); 79 | if(vm.count("both")) 80 | for(size_t t=0; t(); ++t) 81 | { 82 | Particles parts(datSerie%t); 83 | parts.makeRTreeIndex(); 84 | parts.removeShortRange(minSep).exportToFile(outSerie%t); 85 | ++show_progress; 86 | } 87 | else 88 | for(size_t t=0; t(); ++t) 89 | { 90 | Particles(datSerie%t).cut(minSep).exportToFile(outSerie%t); 91 | ++show_progress; 92 | } 93 | } 94 | else 95 | if(vm.count("both")) 96 | { 97 | Particles parts(filename); 98 | parts.makeRTreeIndex(); 99 | parts.removeShortRange(minSep).exportToFile(inputPath+outputPostfix+".dat"); 100 | } 101 | else 102 | Particles(filename).cut(minSep).exportToFile(inputPath+outputPostfix+".dat"); 103 | 104 | 105 | } 106 | catch(const exception &e) 107 | { 108 | cerr<< e.what()<. 18 | **/ 19 | 20 | //Define the preprocessor variable "periodic" if you want periodic boundary conditions 21 | #include "periodic.hpp" 22 | 23 | using namespace std; 24 | using namespace Colloids; 25 | 26 | int main(int argc, char ** argv) 27 | { 28 | try 29 | { 30 | if(argc<3) throw invalid_argument("Syntax : dat2vtk coordinateFile"); 31 | 32 | const string filename(argv[1]); 33 | const string inputPath = filename.substr(0,filename.find_last_of(".")); 34 | const string ext = filename.substr(filename.find_last_of(".")+1); 35 | const size_t tokenPos = inputPath.rfind("_t"); 36 | 37 | Particles parts(filename); 38 | BondSet bonds = loadBonds(inputPath+".bonds"); 39 | 40 | boost::multi_array qw, Sqw; 41 | parts.loadBoo(inputPath+".cloud", qw); 42 | 43 | parts.loadBoo( 44 | inputPath.substr(0, tokenPos)+"_space"+inputPath.substr(tokenPos)+".cloud", 45 | Sqw); 46 | vector scalars; 47 | scalars.reserve(8); 48 | for(size_t i=0;i<4;++i) 49 | scalars.push_back(ScalarField(qw.begin(), qw.end(), "", i)); 50 | for(size_t i=0;i<4;++i) 51 | scalars.push_back(ScalarField(Sqw.begin(), Sqw.end(), "", i)); 52 | for(size_t i=0;i<8;++i) 53 | scalars[i].name = string(i/4?"cg":"")+string((i/2)%2?"W":"Q")+string(i%2?"6":"4"); 54 | 55 | parts.exportToVTK(inputPath+".vtk", bonds, scalars, vector()); 56 | } 57 | catch(const exception &e) 58 | { 59 | cerr<< e.what()< drift(0.0,3); 28 | output << "t\tx\ty\tz" << endl; 29 | 30 | for(size_t t=0;t. 18 | **/ 19 | 20 | #include "dynamicParticles.hpp" 21 | 22 | using namespace std; 23 | using namespace Colloids; 24 | 25 | int main(int argc, char ** argv) 26 | { 27 | if(argc<3) 28 | { 29 | cout << "compute both Mean Square displacement and Self Intermediate scattering function for maximum averaging."<2)?atoi(argv[2]):1; 40 | 41 | try 42 | { 43 | DynamicParticles parts(filename); 44 | if(mode==0 || mode==2) 45 | { 46 | cout <<"No drift removal"<. 18 | **/ 19 | 20 | 21 | #include "dynamicParticles.hpp" 22 | 23 | using namespace std; 24 | using namespace Colloids; 25 | 26 | int main(int argc, char ** argv) 27 | { 28 | if(argc<5) 29 | { 30 | cout << "Syntax : linker [path]filename token radius time_step t_span t_offset(0)" << endl; 31 | return EXIT_FAILURE; 32 | } 33 | 34 | const string filename(argv[1]), token(argv[2]); 35 | const double radius = atof(argv[3]), 36 | time_step= atof(argv[4]); 37 | const size_t t_span = atoi(argv[5]), 38 | t_offset = (argc<7)?0:atoi(argv[6]); 39 | 40 | try 41 | { 42 | FileSerie files(filename, token, t_span, t_offset); 43 | DynamicParticles parts(files, radius, time_step); 44 | cout << "total of " << parts.trajectories.size() << " trajectories" << endl; 45 | 46 | const string head = filename.substr(0,filename.rfind(token)); 47 | const string nofolder = filename.substr(filename.find_last_of("/\\")+1); 48 | parts.save(head+".traj",nofolder,token,t_offset,t_span); 49 | 50 | } 51 | catch(const std::exception &e) 52 | { 53 | cerr <. 18 | **/ 19 | 20 | #include "dynamicClusters.hpp" 21 | 22 | using namespace std; 23 | using namespace Colloids; 24 | 25 | int main(int argc, char ** argv) 26 | { 27 | if(argc<3) 28 | { 29 | cout << "Syntax : percolation [path]filename.dat radius range" << endl; 30 | cout << "\tOR"<> offset >> size; 60 | trajfile.close(); 61 | } 62 | FileSerie datSerie(path+pattern, token, size, offset), 63 | bondSerie = datSerie.changeExt(".bonds"), 64 | clustSerie = datSerie.changeExt(".cluster"); 65 | 66 | 67 | //create the population of trajectories to split into clusters : all trajectories 68 | set alltraj; 69 | for(size_t tr=0;trlow()<<" "<high()<<"\n"; 91 | } 92 | } 93 | 94 | 95 | cout<<"finding the clusters ... "; 96 | DynamicClusters clusters(parts, alltraj); 97 | cout<<"done!"<. 18 | **/ 19 | 20 | //Define the preprocessor variable "use_periodic" if you want periodic boundary conditions 21 | #include "periodic.hpp" 22 | 23 | using namespace std; 24 | using namespace Colloids; 25 | 26 | int main(int argc, char ** argv) 27 | { 28 | try 29 | { 30 | 31 | if(argc<5) 32 | { 33 | cout << "Syntax : [periodic_]rdf [path]filename radius NbOfBins range" << endl; 34 | cout << " range is in diameter unit" << endl; 35 | return EXIT_FAILURE; 36 | } 37 | 38 | cout << "Radial Distribution function" << endl; 39 | const string filename(argv[1]); 40 | const string inputPath = filename.substr(0,filename.find_last_of(".")); 41 | const double radius = atof(argv[2]), 42 | nbDiameterCutOff = atof(argv[4]); 43 | const size_t Nbins = atoi(argv[3]); 44 | 45 | //construct the particle container out of the datafile 46 | #ifdef use_periodic 47 | if(argc<9) 48 | { 49 | cout << "Syntax : periodic_rdf [path]filename radius NbOfBins range Nb dx dy dz" << endl; 50 | cout << " range is in diameter unit" << endl; 51 | return EXIT_FAILURE; 52 | } 53 | const size_t Nb = atoi(argv[5]); 54 | BoundingBox b; 55 | for(size_t d=0;d<3;++d) 56 | { 57 | b.edges[d].first=0.0; 58 | b.edges[d].second = atof(argv[6+d]); 59 | } 60 | PeriodicParticles Centers(Nb,b,filename,radius); 61 | cout << "With periodic boundary conditions"< g = Centers.getRdf(Nbins,nbDiameterCutOff); 71 | cout << " done !" << endl; 72 | 73 | ofstream output((inputPath + ".rdf").c_str(), ios::out | ios::trunc); 74 | output<<"#r\tg"<. 18 | **/ 19 | 20 | //Define the preprocessor variable "use_periodic" if you want periodic boundary conditions 21 | #include "periodic.hpp" 22 | #include "files_series.hpp" 23 | 24 | using namespace std; 25 | using namespace Colloids; 26 | 27 | int main(int argc, char ** argv) 28 | { 29 | try 30 | { 31 | if(argc<5) 32 | { 33 | cout << "Radial Distribution function" << endl; 34 | cout << "Syntax : totalRdf [path]filename _t NbOfBins range" << endl; 35 | cout << " range is in pixel unit." << endl; 36 | return EXIT_FAILURE; 37 | } 38 | 39 | const string filename(argv[1]), token(argv[2]); 40 | const string inputPath = filename.substr(0,filename.rfind(token)); 41 | const double range = atof(argv[4]); 42 | const size_t Nbins = atoi(argv[3]); 43 | cout<<"Nbins="<::iterator firstPeak = max_element(gTot.begin(),gTot.end()); 66 | vector::iterator firstMin = min_element(firstPeak,gTot.end()); 67 | cout<<(firstPeak-gTot.begin())*range/Nbins<<"\t"<<2.0*(firstPeak-gTot.begin())/(double)(firstMin-gTot.begin())< 10 | #include 11 | 12 | namespace Colloids { 13 | 14 | Convolver::Convolver(unsigned long int size) : _size(size), _fourier_size(size/2+1) 15 | { 16 | this->real = (float *) fftwf_malloc(sizeof(float) * this->_size); 17 | this->fourier = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex) * this->_fourier_size); 18 | this->forward = fftwf_plan_dft_r2c_1d(this->_size, this->real, this->fourier, 19 | FFTW_MEASURE); 20 | this->backward = fftwf_plan_dft_c2r_1d(this->_size, this->fourier, this->real, 21 | FFTW_MEASURE); 22 | } 23 | 24 | Convolver::~Convolver() 25 | { 26 | fftwf_destroy_plan(this->forward); 27 | fftwf_destroy_plan(this->backward); 28 | fftwf_free(real); fftwf_free(fourier); 29 | } 30 | 31 | void Convolver::spectrum(const float *input, int step, float *output) 32 | { 33 | this->fill(input, step); 34 | fftwf_execute(this->forward); 35 | for (unsigned long int i=0; i_fourier_size; ++i) 36 | *output++ = std::norm(*reinterpret_cast*>(this->fourier+i)); 37 | } 38 | 39 | void Convolver::operator()(float* input, const int step, const float* kernel) 40 | { 41 | this->fill(input, step); 42 | fftwf_execute(this->forward); 43 | for(unsigned long int i=0; i_fourier_size; ++i) 44 | { 45 | const float factor = *kernel++ / this->_size; 46 | this->fourier[i][0] *= factor; 47 | this->fourier[i][1] *= factor; 48 | } 49 | fftwf_execute(this->backward); 50 | for (unsigned long int i=0; i_size; ++i) 51 | { 52 | *input = this->real[i]; 53 | input += step; 54 | } 55 | } 56 | void Convolver::fill(const float* input, const int step) 57 | { 58 | for(size_t i=0; i_size; ++i) 59 | { 60 | this->real[i] = *input; 61 | input += step; 62 | } 63 | if(this->windowing()) 64 | { 65 | for(size_t i=0; i_size; ++i) 66 | this->real[i] *= this->window[i]; 67 | } 68 | } 69 | void Convolver::set_hanning() 70 | { 71 | this->window.resize(this->size(), 1.0); 72 | for(int i=0; isize(); ++i) 73 | this->window[i] = 0.5 *(1.0 - cos(2*M_PI*i/(this->size()-1))); 74 | } 75 | 76 | std::vector get_spectrum_1d(const cv::Mat_ &im, const int axis, const bool windowing) 77 | { 78 | if(axis >= im.dims) 79 | throw std::invalid_argument("Matrix dimension is too small to compute the spectrum along this axis"); 80 | assert(im.isContinuous()); 81 | Convolver co(im.size[axis]); 82 | if(windowing) 83 | co.set_hanning(); 84 | std::vector spectrum(co.fourier_size()); 85 | std::vector tot(co.fourier_size(), 0.0); 86 | std::vector > totf(co.fourier_size(), 0.0); 87 | unsigned long int step = im.step1(axis); 88 | //whatever the real dimension, we fall back to a 3d situation where the axis of interest is y 89 | //and either x or z can be of size 1 90 | int nbplanes = 1; 91 | for(int d=0; d(im.data) + i*planestep + j, step, &spectrum[0]); 101 | for(size_t u=0; u get_deconv_kernel(const cv::Mat_ &im, const int good_axis, const int bad_axis, const double size_ratio) 114 | { 115 | std::vector bad_sp = get_spectrum_1d(im, bad_axis); 116 | std::vector good_sp = get_spectrum_1d(im, good_axis); 117 | //linear interpolation of good_sp to take into account the voxel size ratio 118 | const double qratio = bad_sp.size() * size_ratio / good_sp.size(); 119 | std::vector scaled(std::min(bad_sp.size(), (size_t)((good_sp.size()-1)*qratio)), 0); 120 | for(size_t i=0; i kernel(bad_sp.size(), 1.0f); 129 | for(size_t i=0; i1.0f) 131 | kernel[i] = sqrt(scaled[i]/bad_sp[i]); 132 | return kernel; 133 | } 134 | 135 | void convolve(cv::Mat_ &im, const int axis, const float* kernel) 136 | { 137 | if(axis >= im.dims) 138 | throw std::invalid_argument("Matrix dimension is too small to convolve along this axis"); 139 | assert(im.isContinuous()); 140 | Convolver co(im.size[axis]); 141 | unsigned long int step = im.step1(axis); 142 | //whatever the real dimension, we fall back to a 3d situation where the axis of interest is y 143 | //and either x or z can be of size 1 144 | int nbplanes = 1; 145 | for(int d=0; d(im.data) + i*planestep + j, step, kernel); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /multiscale/src/deconvolution.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * deconvolution.hpp 3 | * 4 | * Created on: 13 avr. 2012 5 | * Author: mathieu 6 | */ 7 | 8 | #ifndef DECONVOLUTION_HPP_ 9 | #define DECONVOLUTION_HPP_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace Colloids { 17 | 18 | class Convolver 19 | { 20 | public: 21 | //constructor, destructor 22 | Convolver(unsigned long int size); 23 | ~Convolver(); 24 | 25 | //accessors 26 | int size(){return this->_size;} 27 | int fourier_size(){return this->_fourier_size;} 28 | const std::complex* get_fourier(){return reinterpret_cast*>(this->fourier);} 29 | 30 | //processing 31 | /** 32 | * \brief Compute the spectrum of a (possibly discontinuous) input 33 | */ 34 | void spectrum(const float* input, const int step, float* output); 35 | /** 36 | * \brief Convolve in place the (possibly discontinuous) input with the kernel (given in Fourier space) 37 | */ 38 | void operator()(float* input, const int step, const float* kernel); 39 | /** 40 | * \brief set the window function to Hanning 41 | */ 42 | void set_hanning(); 43 | void unset_window(){this->window.clear();} 44 | bool windowing(){return !this->window.empty();} 45 | 46 | protected: 47 | unsigned long int _size; 48 | unsigned long int _fourier_size; 49 | float* real; 50 | fftwf_complex* fourier; 51 | fftwf_plan forward, backward; 52 | std::vector window; 53 | void fill(const float* input, const int step); 54 | }; 55 | 56 | std::vector get_spectrum_1d(const cv::Mat_ &im, const int axis=0, const bool windowing=true); 57 | std::vector get_deconv_kernel(const cv::Mat_ &im, const int good_axis, const int bad_axis, const double size_ratio=1.0); 58 | void convolve(cv::Mat_ &im, const int axis, const float* kernel); 59 | 60 | } 61 | 62 | #endif /* DECONVOLUTION_HPP_ */ 63 | -------------------------------------------------------------------------------- /multiscale/src/locatorfromlif.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * liffinder.cpp 3 | * 4 | * Created on: 11 août 2011 5 | * Author: mathieu 6 | */ 7 | 8 | #include "locatorfromlif.hpp" 9 | 10 | namespace Colloids { 11 | 12 | LocatorFromLif::LocatorFromLif(LifSerie * serie): 13 | serie(serie), t(0), input(serie->begin()) 14 | { 15 | this->dims = serie->getSpatialDimensions(); 16 | this->total_z = this->dims.size()>2 ? this->dims[2] : 1; 17 | this->total_t = serie->getNbTimeSteps(); 18 | this->finder.reset(new MultiscaleFinder2D(dims[0], dims[1])); 19 | this->slice.create(dims[0], dims[1]); 20 | this->slice.setTo(0); 21 | } 22 | 23 | LocatorFromLif::~LocatorFromLif() { 24 | // TODO Auto-generated destructor stub 25 | } 26 | 27 | void LocatorFromLif::clear() 28 | { 29 | this->slice.setTo(0); 30 | this->rec.clear(); 31 | } 32 | 33 | /** \brief Read the next 2D slice from the lif file, track it and add it to the reconstructor */ 34 | void LocatorFromLif::fill_next_slice() 35 | { 36 | std::vector centers; 37 | if(this->t >= this->total_t || this->get_z() >= this->total_z) 38 | throw std::out_of_range("End of file reached"); 39 | this->serie->fill2DBuffer(static_cast(this->slice.data), 0, this->get_z());//this->t, this->get_z()); 40 | this->finder->get_centers(this->slice, centers); 41 | this->rec.push_back(centers); 42 | } 43 | 44 | void LocatorFromLif::fill_time_step() 45 | { 46 | //ensure that we start at the beginning of the stack 47 | this->clear(); 48 | //track each slice 49 | for(size_t z=0; ztotal_z; ++z) 50 | this->fill_next_slice(); 51 | } 52 | void LocatorFromLif::get_centers(Centers & centers) 53 | { 54 | 55 | //3D reconstruction 56 | //this->rec.split_clusters(); 57 | this->rec.get_blobs(centers); 58 | //convert the z coordinate according to the z-spacing of acquisition 59 | for(Centers::iterator c=centers.begin(); c!=centers.end(); ++c) 60 | (*c)[2] *= this->serie->getZXratio(); 61 | this->t++; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /multiscale/src/locatorfromlif.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * liffinder.h 3 | * 4 | * Created on: 11 août 2011 5 | * Author: mathieu 6 | */ 7 | 8 | #ifndef LIFFINDER_H_ 9 | #define LIFFINDER_H_ 10 | 11 | #include "lifFile.hpp" 12 | #include "reconstructor.hpp" 13 | #include "multiscalefinder.hpp" 14 | 15 | namespace Colloids { 16 | 17 | class LocatorFromLif { 18 | public: 19 | typedef Reconstructor::OutputType Centers; 20 | explicit LocatorFromLif(LifSerie * serie); 21 | virtual ~LocatorFromLif(); 22 | 23 | //accessors 24 | const Reconstructor & get_reconstructor() const {return this->rec;}; 25 | const cv::Mat_ & get_slice() const {return this->slice;}; 26 | const size_t get_z() const {return get_reconstructor().size();} 27 | const size_t size() const {return total_t;} 28 | const size_t & get_t() const {return t;} 29 | const MultiscaleFinder2D& get_finder() const{return *finder;} 30 | 31 | //processing 32 | void clear(); 33 | void fill_next_slice(); 34 | void fill_time_step(); 35 | void get_centers(Centers ¢ers); 36 | 37 | private: 38 | LifSerie * serie; 39 | std::auto_ptr finder; 40 | Reconstructor rec; 41 | cv::Mat_ slice; 42 | std::vector dims; 43 | size_t t, total_t, total_z; 44 | std::istreambuf_iterator input; 45 | }; 46 | 47 | } 48 | 49 | #endif /* LIFFINDER_H_ */ 50 | -------------------------------------------------------------------------------- /multiscale/src/reconstructor.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * reconstructor.h 3 | * 4 | * Created on: 3 août 2011 5 | * Author: mathieu 6 | */ 7 | 8 | #ifndef RECONSTRUCTOR_H_ 9 | #define RECONSTRUCTOR_H_ 10 | 11 | #include "center.hpp" 12 | #include "traj.hpp" 13 | #include 14 | #include 15 | #include 16 | 17 | namespace Colloids 18 | { 19 | 20 | class Reconstructor :boost::noncopyable 21 | { 22 | public: 23 | typedef std::list Cluster; 24 | typedef std::vector Frame; 25 | typedef std::deque OutputType; 26 | typedef RStarTree RTree; 27 | 28 | Reconstructor(); 29 | virtual ~Reconstructor(); 30 | 31 | //accessors 32 | inline bool empty() const {return !trajectories.get();} 33 | inline const size_t size() const {return empty()?0:trajectories->nbFrames();} 34 | inline const size_t nb_cluster() const {return clusters.size();} 35 | inline const std::deque& get_clusters() const {return clusters;} 36 | inline const TrajIndex& get_trajectories() const {assert(!empty()); return *trajectories;} 37 | 38 | //processing 39 | void clear(); 40 | void push_back(const Frame &fr, const double &max_dist=1.0); 41 | void split_clusters(); 42 | void get_blobs(OutputType& blobs); 43 | 44 | private: 45 | std::auto_ptr trajectories; 46 | std::deque clusters; 47 | Frame last_frame; 48 | 49 | void links_by_brute_force(const Frame& fr, std::vector &distances, std::vector &from, std::vector &to, const double &tolerance=1.0) const; 50 | void links_by_RStarTree(const Frame& fr, const RTree& tree, std::vector &distances, std::vector &from, std::vector &to, const double &max_dist=1.0) const; 51 | void links_by_kdtree(const Frame& fr, std::vector &distances, std::vector &from, std::vector &to, const double &tolerance=1.0) const; 52 | 53 | }; 54 | 55 | } 56 | 57 | #endif /* RECONSTRUCTOR_H_ */ 58 | -------------------------------------------------------------------------------- /multiscale/src/traj.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2008,2009 Mathieu Leocmach 3 | 4 | This file is part of Colloids. 5 | 6 | Colloids is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | Colloids is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Colloids. If not, see . 18 | **/ 19 | 20 | #include "traj.hpp" 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | 26 | namespace Colloids { 27 | 28 | struct Link : std::pair 29 | { 30 | double distance; 31 | Link(const size_t &a, const size_t &b, const double &distance) : 32 | std::pair(a,b), distance(distance){}; 33 | 34 | bool operator<(const Link &other) const {return this->distancetr2pos.push_back(new Traj(0, p)); 43 | this->pos2tr.push_back(new std::vector(nb_initial_positions)); 44 | for(size_t p=0; ppos2tr[0][p] = p; 46 | } 47 | 48 | void TrajIndex::add_Frame(const size_t &frame_size, const std::vector &distances, const std::vector &p_from, const std::vector &p_to) 49 | { 50 | if(distances.size() != p_from.size() || p_from.size() != p_to.size()) 51 | throw std::invalid_argument("TrajIndex::add_Frame: All arguments must have the same size"); 52 | if(!p_to.empty() && *std::max_element(p_to.begin(), p_to.end()) >= frame_size) 53 | throw std::invalid_argument("TrajIndex::add_Frame: The largest particle index in the new frame is larger than the new frame size"); 54 | std::list bonds; 55 | for(size_t i=0; i< distances.size(); ++i) 56 | bonds.push_back(Link(p_from[i], p_to[i], distances[i])); 57 | //sort the bonds by increasing distances 58 | bonds.sort(); 59 | //any position can be linked only once 60 | std::vector from_used(this->pos2tr.back().size(), false), to_used(frame_size, false); 61 | //create the new frame 62 | this->pos2tr.push_back(new std::vector(frame_size)); 63 | //link the bounded positions into trajectories 64 | for(std::list::const_iterator b= bonds.begin(); b!=bonds.end(); ++b) 65 | if(!from_used[b->first] && !to_used[b->second]) 66 | { 67 | from_used[b->first] = true; 68 | to_used[b->second] = true; 69 | const size_t tr = this->pos2tr[this->pos2tr.size()-2][b->first]; 70 | this->pos2tr.back()[b->second] = tr; 71 | this->tr2pos[tr].push_back(b->second); 72 | } 73 | //the trajectories of the previous frame that are not linked in the new frame are terminated by construction 74 | //but the trajectories starting in the new frame have to be created 75 | for(size_t p=0; ppos2tr.back()[p] = this->tr2pos.size(); 79 | this->tr2pos.push_back(new Traj(this->pos2tr.size()-1, p)); 80 | } 81 | } 82 | 83 | } //Name space 84 | -------------------------------------------------------------------------------- /multiscale/test/lifTrack.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_DYN_LINK 2 | 3 | #include "../src/multiscalefinder.hpp" 4 | #include "../src/traj.hpp" 5 | #include "../src/reconstructor.hpp" 6 | #include "../src/locatorfromlif.hpp" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace Colloids; 17 | using namespace boost::posix_time; 18 | 19 | BOOST_AUTO_TEST_SUITE( LifTrack ) 20 | /*BOOST_AUTO_TEST_CASE( fill_one_slice ) 21 | { 22 | LifReader reader("/home/mathieu/Code_data/liftest/Tsuru11dm_phi=52.53_J36.lif"); 23 | LocatorFromLif locator(&reader.getSerie(0)); 24 | BOOST_CHECK_EQUAL(cv::sum(locator.get_slice())[0], 0); 25 | locator.fill_next_slice(); 26 | BOOST_CHECK_EQUAL(cv::sum(locator.get_slice())[0], 5357342); 27 | BOOST_CHECK_EQUAL(locator.get_reconstructor().size(), 1); 28 | locator.clear(); 29 | BOOST_CHECK_EQUAL(cv::sum(locator.get_slice())[0], 0); 30 | BOOST_CHECK_EQUAL(locator.get_z(), 0); 31 | MultiscaleFinder2D finder; 32 | cv::Mat_ slice(256, 256, (unsigned char)0); 33 | reader.getSerie(0).fill2DBuffer(static_cast(slice.data), 0, 114); 34 | std::vector centers = finder(slice); 35 | for(size_t l=1; l Clusters; 65 | const Clusters & clusters = locator.get_reconstructor().get_clusters(); 66 | Clusters::const_iterator cl_min=clusters.begin(); 67 | int count_file =0; 68 | //their may be too many clusters than the maximum of int type, so we have to divide in several files 69 | while(cl_min!=clusters.end()) 70 | { 71 | Clusters::const_iterator cl_max = cl_min; 72 | size_t nb = 0, nb_cl=0; 73 | while(cl_max!=clusters.end() && (nb + cl_max->size() + nb_cl +1 < (size_t)std::numeric_limits::max())) 74 | { 75 | nb += cl_max->size(); 76 | nb_cl++; 77 | cl_max++; 78 | } 79 | std::cout<<"file "<begin(); p!=cl->end(); ++p) 90 | { 91 | for(size_t d=0;d<3;++d) 92 | f_cl<<(*p)[d]<<" "; 93 | f_cl<<"\n"; 94 | } 95 | f_cl<< "LINES "<size()<<" "; 100 | for(size_t p=0; psize();++p) 101 | f_cl<< l++ <<" "; 102 | f_cl<<"\n"; 103 | } 104 | f_cl<<"POINT_DATA "<begin(); p!=cl->end(); ++p) 109 | f_cl<< p->r <<"\n"; 110 | f_cl<<"SCALARS response double\n" 111 | "LOOKUP_TABLE default\n"; 112 | for(Clusters::const_iterator cl=cl_min;cl!=cl_max;++cl) 113 | for(Cluster::const_iterator p = cl->begin(); p!=cl->end(); ++p) 114 | f_cl<< p->intensity <<"\n"; 115 | f_cl.close(); 116 | cl_min = cl_max; 117 | } 118 | 119 | LocatorFromLif::Centers centers; 120 | { 121 | std::cout<<"get_centers "; 122 | boost::progress_timer ti; 123 | locator.get_centers(centers); 124 | } 125 | std::cout<r <<"\n"; 147 | f_rec.close(); 148 | } 149 | BOOST_AUTO_TEST_SUITE_END() 150 | -------------------------------------------------------------------------------- /multiscale/test/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define BOOST_TEST_MODULE multiscale test 3 | #define BOOST_TEST_DYN_LINK 4 | 5 | #include 6 | #include "../src/multiscalefinder.hpp" 7 | 8 | using namespace Colloids; 9 | 10 | void images_are_close(const cv::Mat &a, const cv::Mat &b, float precision) 11 | { 12 | OctaveFinder::Image M = cv::abs(a)+cv::abs(b); 13 | double peak = *std::max_element(M.begin(), M.end()); 14 | BOOST_REQUIRE_CLOSE(cv::sum(a)[0], cv::sum(b)[0], precision/peak); 15 | cv::Mat_ diff = cv::abs(a-b) / peak; 16 | cv::MatConstIterator_ u = diff.begin(); 17 | for(int i=0; i "< 5 | 6 | using namespace Colloids; 7 | 8 | BOOST_AUTO_TEST_SUITE( Overlap ) 9 | BOOST_AUTO_TEST_CASE(Overlap_RTree) 10 | { 11 | typedef RStarTree RTree; 12 | std::vector centers; 13 | std::auto_ptr tree = removeOverlapping(centers); 14 | BOOST_REQUIRE(centers.empty()); 15 | Center2D c(0, 1, 0); 16 | centers.push_back(c); 17 | tree = removeOverlapping(centers); 18 | BOOST_REQUIRE_EQUAL(centers.size(), 1); 19 | centers.push_back(c); 20 | tree = removeOverlapping(centers); 21 | BOOST_REQUIRE_EQUAL(centers.size(), 1); 22 | c.intensity = -1.0; 23 | centers.push_back(c); 24 | tree = removeOverlapping(centers); 25 | BOOST_REQUIRE_EQUAL(centers.size(), 1); 26 | BOOST_CHECK_CLOSE(centers[0].intensity, -1, 1e-9); 27 | c[0] = 3; 28 | c.intensity = -2.0; 29 | centers.push_back(c); 30 | tree = removeOverlapping(centers); 31 | BOOST_REQUIRE_EQUAL(centers.size(), 2); 32 | BOOST_CHECK_CLOSE(centers[0].intensity, -2, 1e-9); 33 | BOOST_CHECK_CLOSE(centers[1].intensity, -1, 1e-9); 34 | c[0] = 2; 35 | c.intensity = 0; 36 | c.r = 1.1; 37 | centers.push_back(c); 38 | tree = removeOverlapping(centers); 39 | BOOST_REQUIRE_EQUAL(centers.size(), 2); 40 | BOOST_CHECK_CLOSE(centers[0].intensity, -2, 1e-9); 41 | BOOST_CHECK_CLOSE(centers[1].intensity, -1, 1e-9); 42 | c.intensity = -1.5; 43 | centers.push_back(c); 44 | tree = removeOverlapping(centers); 45 | BOOST_REQUIRE_EQUAL(centers.size(), 2); 46 | BOOST_CHECK_CLOSE(centers[0].intensity, -2, 1e-9); 47 | BOOST_CHECK_CLOSE(centers[1].intensity, -1, 1e-9); 48 | c.intensity = -3.0; 49 | centers.push_back(c); 50 | tree = removeOverlapping(centers); 51 | BOOST_REQUIRE_EQUAL(centers.size(), 1); 52 | BOOST_CHECK_CLOSE(centers[0].intensity, -3, 1e-9); 53 | } 54 | BOOST_AUTO_TEST_CASE(Overlap_Brute) 55 | { 56 | std::vector centers; 57 | removeOverlapping_brute_force(centers); 58 | BOOST_REQUIRE(centers.empty()); 59 | Center2D c(0, 1, 0); 60 | centers.push_back(c); 61 | removeOverlapping_brute_force(centers); 62 | BOOST_REQUIRE_EQUAL(centers.size(), 1); 63 | centers.push_back(c); 64 | removeOverlapping_brute_force(centers); 65 | BOOST_REQUIRE_EQUAL(centers.size(), 1); 66 | c.intensity = -1.0; 67 | centers.push_back(c); 68 | removeOverlapping_brute_force(centers); 69 | BOOST_REQUIRE_EQUAL(centers.size(), 1); 70 | BOOST_CHECK_CLOSE(centers[0].intensity, -1, 1e-9); 71 | c[0] = 3; 72 | c.intensity = -2.0; 73 | centers.push_back(c); 74 | removeOverlapping_brute_force(centers); 75 | BOOST_REQUIRE_EQUAL(centers.size(), 2); 76 | BOOST_CHECK_CLOSE(centers[0].intensity, -2, 1e-9); 77 | BOOST_CHECK_CLOSE(centers[1].intensity, -1, 1e-9); 78 | c[0] = 2; 79 | c.intensity = 0; 80 | c.r = 1.1; 81 | centers.push_back(c); 82 | removeOverlapping_brute_force(centers); 83 | BOOST_REQUIRE_EQUAL(centers.size(), 2); 84 | BOOST_CHECK_CLOSE(centers[0].intensity, -2, 1e-9); 85 | BOOST_CHECK_CLOSE(centers[1].intensity, -1, 1e-9); 86 | c.intensity = -1.5; 87 | centers.push_back(c); 88 | removeOverlapping_brute_force(centers); 89 | BOOST_REQUIRE_EQUAL(centers.size(), 2); 90 | BOOST_CHECK_CLOSE(centers[0].intensity, -2, 1e-9); 91 | BOOST_CHECK_CLOSE(centers[1].intensity, -1, 1e-9); 92 | c.intensity = -3.0; 93 | centers.push_back(c); 94 | removeOverlapping_brute_force(centers); 95 | BOOST_REQUIRE_EQUAL(centers.size(), 1); 96 | BOOST_CHECK_CLOSE(centers[0].intensity, -3, 1e-9); 97 | } 98 | BOOST_AUTO_TEST_SUITE_END() 99 | -------------------------------------------------------------------------------- /multiscale/test/trajectories.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_DYN_LINK 2 | 3 | #include "../src/traj.hpp" 4 | #include 5 | #include 6 | 7 | using namespace Colloids; 8 | 9 | BOOST_AUTO_TEST_SUITE( trajectories ) 10 | BOOST_AUTO_TEST_CASE( traj ) 11 | { 12 | Traj traj(-1, 5); 13 | BOOST_CHECK_EQUAL(traj.get_start(), -1); 14 | BOOST_CHECK_EQUAL(traj.get_finish(), 0); 15 | BOOST_CHECK_EQUAL(traj[-1], 5); 16 | traj.push_back(2); 17 | BOOST_CHECK_EQUAL(traj.get_start(), -1); 18 | BOOST_CHECK_EQUAL(traj.get_finish(), 1); 19 | BOOST_CHECK_EQUAL(traj[-1], 5); 20 | BOOST_CHECK_EQUAL(traj[0], 2); 21 | } 22 | BOOST_AUTO_TEST_CASE( trajindex ) 23 | { 24 | TrajIndex ti(2); 25 | BOOST_REQUIRE_EQUAL(ti.nbFrames(), 1); 26 | BOOST_REQUIRE_EQUAL(ti.size(), 2); 27 | BOOST_REQUIRE_EQUAL(ti.getInverse(0).size(), 2); 28 | for(size_t p = 0; p from(6), to(6); 33 | std::fill_n(from.begin(), 3, 0); 34 | std::fill_n(from.rbegin(), 3, 1); 35 | to[0] = 0; 36 | to[1] = 1; 37 | to[2] = 2; 38 | to[3] = 0; 39 | to[4] = 1; 40 | to[5] = 2; 41 | std::vector distances(6); 42 | distances[0] = 1,1; 43 | distances[1] = 1.2; 44 | distances[2] = 0.9; 45 | distances[3] = 0.1; 46 | distances[4] = 1.1; 47 | distances[5] = 1.0; 48 | //case where we have more new positions than old ones 49 | ti.add_Frame(4, distances, from, to); 50 | BOOST_REQUIRE_EQUAL(ti.nbFrames(), 2); 51 | BOOST_REQUIRE_EQUAL(ti.getInverse(1).size(), 4); 52 | BOOST_REQUIRE_EQUAL(ti[1].size(), 2); 53 | BOOST_CHECK_EQUAL(ti[1][1], 0); 54 | BOOST_CHECK_EQUAL(ti.getTraj(1,0), 1); 55 | BOOST_REQUIRE_EQUAL(ti[0].size(), 2); 56 | BOOST_CHECK_EQUAL(ti[0][1], 2); 57 | BOOST_CHECK_EQUAL(ti.getTraj(1,2), 0); 58 | BOOST_REQUIRE(ti[2].exist(1)); 59 | BOOST_CHECK_EQUAL(ti[2][1], 1); 60 | BOOST_CHECK_EQUAL(ti.getTraj(1,1), 2); 61 | BOOST_REQUIRE(ti[3].exist(1)); 62 | BOOST_CHECK_EQUAL(ti[3][1], 3); 63 | BOOST_CHECK_EQUAL(ti.getTraj(1,3), 3); 64 | BOOST_REQUIRE_EQUAL(ti.size(), 4); 65 | 66 | //case where we have less positions than old ones 67 | ti.add_Frame(3, distances, from, to); 68 | BOOST_REQUIRE_EQUAL(ti.nbFrames(), 3); 69 | BOOST_REQUIRE_EQUAL(ti.size(), 5); 70 | BOOST_REQUIRE_EQUAL(ti.getInverse(2).size(), 3); 71 | BOOST_CHECK_EQUAL(ti[0].size(), 2); 72 | BOOST_REQUIRE_EQUAL(ti[1].size(), 3); 73 | BOOST_CHECK_EQUAL(ti[1][2], 2); 74 | BOOST_CHECK_EQUAL(ti.getTraj(2,2), 1); 75 | BOOST_CHECK(ti[2].exist(2)); 76 | BOOST_CHECK_EQUAL(ti[2][2], 0); 77 | BOOST_CHECK_EQUAL(ti.getTraj(2,0), 2); 78 | BOOST_CHECK(!ti[3].exist(2)); 79 | BOOST_CHECK(ti[4].exist(2)); 80 | BOOST_CHECK_EQUAL(ti[4][2], 1); 81 | BOOST_CHECK_EQUAL(ti.getTraj(2,1), 4); 82 | 83 | //load a smaller frame 84 | boost::array fr0 = {{2, 1}}; 85 | ti.add_Frame(fr0.begin(), fr0.end()); 86 | BOOST_REQUIRE_EQUAL(ti.nbFrames(), 4); 87 | BOOST_REQUIRE_EQUAL(ti.size(), 5); 88 | BOOST_REQUIRE_EQUAL(ti.getInverse(3).size(), 2); 89 | BOOST_CHECK_EQUAL(ti[0].size(), 2); 90 | BOOST_REQUIRE_EQUAL(ti[1].size(), 4); 91 | BOOST_CHECK_EQUAL(ti[1][3], 1); 92 | BOOST_CHECK_EQUAL(ti.getTraj(3,1), 1); 93 | BOOST_CHECK(ti[2].exist(3)); 94 | BOOST_CHECK_EQUAL(ti[2][3], 0); 95 | BOOST_CHECK_EQUAL(ti.getTraj(3,0), 2); 96 | BOOST_CHECK(!ti[3].exist(3)); 97 | BOOST_CHECK(!ti[4].exist(3)); 98 | 99 | //load a larger frame 100 | boost::array fr1 = {{2, 1, 5}}; 101 | ti.add_Frame(fr1.begin(), fr1.end()); 102 | BOOST_REQUIRE_EQUAL(ti.nbFrames(), 5); 103 | BOOST_REQUIRE_EQUAL(ti.size(), 6); 104 | BOOST_REQUIRE_EQUAL(ti.getInverse(4).size(), 3); 105 | BOOST_REQUIRE_EQUAL(ti[1].size(), 5); 106 | BOOST_CHECK_EQUAL(ti[1][4], 1); 107 | BOOST_CHECK_EQUAL(ti.getTraj(4,1), 1); 108 | BOOST_REQUIRE(ti[2].exist(4)); 109 | BOOST_CHECK_EQUAL(ti[2][4], 0); 110 | BOOST_CHECK_EQUAL(ti.getTraj(4,0), 2); 111 | BOOST_REQUIRE(ti[5].exist(4)); 112 | BOOST_CHECK_EQUAL(ti[5][4], 2); 113 | BOOST_CHECK_EQUAL(ti.getTraj(4,2), 5); 114 | 115 | //frame with no link 116 | ti.add_Frame(4, std::vector(), std::vector(), std::vector()); 117 | BOOST_REQUIRE_EQUAL(ti.nbFrames(), 6); 118 | BOOST_REQUIRE_EQUAL(ti.size(), 10); 119 | BOOST_REQUIRE_EQUAL(ti.getInverse(5).size(), 4); 120 | BOOST_REQUIRE_EQUAL(ti[1].size(), 5); 121 | BOOST_CHECK_EQUAL(ti[1][4], 1); 122 | BOOST_CHECK_EQUAL(ti.getTraj(4,1), 1); 123 | BOOST_REQUIRE(!ti[2].exist(5)); 124 | BOOST_CHECK_EQUAL(ti[2][4], 0); 125 | BOOST_CHECK_EQUAL(ti.getTraj(4,0), 2); 126 | BOOST_REQUIRE(!ti[5].exist(5)); 127 | BOOST_CHECK_EQUAL(ti[5][4], 2); 128 | BOOST_CHECK_EQUAL(ti.getTraj(4,2), 5); 129 | 130 | } 131 | BOOST_AUTO_TEST_SUITE_END() 132 | -------------------------------------------------------------------------------- /multiscale/test_input/Gel_3_9_15_decon2.lif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/multiscale/test_input/Gel_3_9_15_decon2.lif -------------------------------------------------------------------------------- /multiscale/test_input/Playing_JH2.lif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/multiscale/test_input/Playing_JH2.lif -------------------------------------------------------------------------------- /multiscale/test_input/Z_elong.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/multiscale/test_input/Z_elong.raw -------------------------------------------------------------------------------- /multiscale/test_input/Z_preblur.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/multiscale/test_input/Z_preblur.raw -------------------------------------------------------------------------------- /multiscale/test_input/gel.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/multiscale/test_input/gel.raw -------------------------------------------------------------------------------- /multiscale/test_input/real.blob: -------------------------------------------------------------------------------- 1 | 83.219 152.803 77 2.83824 -7.41422 2 | 83.3436 153.253 78 3.06296 -11.5007 3 | 83.3032 153.407 79 3.37865 -12.7026 4 | 83.351 153.693 80 3.53789 -13.6815 5 | 83.7386 153.669 81 3.57596 -14.4371 6 | 83.7329 153.443 82 3.57546 -13.6481 7 | 83.8235 153.718 83 3.39026 -13.5807 8 | 83.9851 153.748 84 3.23713 -11.8785 9 | 84.1813 153.858 85 3.19057 -10.532 10 | 84.5342 153.548 86 3.03982 -10.6017 11 | 85.01 153.591 87 3.12924 -9.85892 12 | 85.4804 153.673 88 3.27906 -11.1189 13 | 85.5591 153.645 89 3.48833 -11.5943 14 | 85.9306 153.489 90 3.75683 -13.8704 15 | 86.0412 153.354 91 3.88221 -14.0072 16 | 86.1085 152.966 92 3.89088 -14.9101 17 | 86.2135 153.065 93 3.83433 -14.384 18 | 86.329 152.813 94 3.63634 -13.034 19 | 86.0367 153.031 95 3.57596 -12.6378 20 | 86.3542 153.251 96 3.135 -11.3687 21 | 86.4879 153.355 97 3.05413 -8.60226 22 | 86.7336 153.696 98 2.95361 -8.48206 23 | 86.6595 153.88 99 3.11341 -8.83379 24 | 87.0308 153.884 100 3.12905 -10.0641 25 | 87.2475 153.754 101 3.28451 -11.0496 26 | 87.1557 154.163 102 3.41878 -14.1459 27 | 87.6115 154.081 103 3.52226 -14.9553 28 | 87.644 153.693 104 3.57596 -14.2645 29 | 87.7731 153.81 105 3.57596 -14.0979 30 | 87.966 153.625 106 3.37093 -12.2102 31 | 87.964 153.85 107 3.25041 -9.92972 32 | 88.1825 153.375 108 3.17276 -8.98586 33 | 88.6515 152.579 109 3.12169 -6.45284 34 | 88.8769 151.717 110 3.04747 -7.66286 35 | 88.9136 151.051 111 3.30347 -9.05953 36 | 89.056 150.934 112 3.43427 -11.1272 37 | 89.2388 150.864 113 3.57596 -11.6557 38 | 89.295 150.653 114 3.57596 -14.3907 39 | 89.1285 151.047 115 3.56991 -13.6947 40 | 89.3113 151.084 116 3.57596 -11.9971 41 | 89.4011 151.237 117 3.35113 -11.2497 42 | 89.6096 151.415 118 3.23361 -10.4258 43 | 90.2005 151.967 119 3.10925 -7.95742 44 | 90.4275 152.31 120 3.21561 -8.37287 45 | 90.6459 152.408 121 3.34489 -8.85593 46 | 90.8694 152.46 122 3.34707 -10.4297 47 | 90.9868 152.89 123 3.47309 -10.2008 48 | 91.4167 152.91 124 3.80835 -10.6492 49 | 91.5119 153.239 125 3.71367 -12.4264 50 | 91.266 153.305 126 3.75995 -10.9431 51 | 91.3791 153.404 127 3.63184 -10.4915 52 | 91.6328 153.523 128 3.44083 -9.0809 53 | 91.4394 153.871 129 3.27604 -8.37031 54 | 91.271 154.456 130 3.0939 -6.84948 55 | 91.5059 154.867 131 3.11776 -5.85826 56 | 91.3877 155.329 132 3.17848 -7.28577 57 | 91.044 155.834 133 3.30043 -7.57088 58 | 91.1418 155.827 134 3.43699 -8.79633 59 | 91.0956 156.266 135 3.41458 -10.0439 60 | 90.7239 155.732 136 3.38073 -9.47263 61 | 90.8013 156.095 137 3.52959 -8.02196 62 | 91.03 155.962 138 3.21927 -8.24496 63 | 90.8558 155.924 139 3.21858 -7.7552 64 | 90.4017 156.168 140 3.04352 -7.588 65 | 89.8016 156.047 141 2.77339 -7.15126 66 | 89.7728 156.702 142 3.04306 -7.12591 67 | 89.4345 156.582 143 3.13514 -9.06391 68 | 89.4338 156.585 144 3.44906 -8.72887 69 | 89.2485 156.602 145 3.45971 -10.5237 70 | 89.2184 156.699 146 3.74438 -9.89185 71 | 89.2082 156.753 147 3.57596 -10.0855 72 | 89.0806 155.934 148 3.4845 -9.79817 73 | 89.2677 156.338 149 3.43311 -8.61163 74 | 89.2909 156.15 150 3.4303 -7.25658 75 | -------------------------------------------------------------------------------- /multiscale/test_input/real2.blob: -------------------------------------------------------------------------------- 1 | 91.2216 158.257 70 3.00463 -6.77686 2 | 90.958 158.273 71 3.3131 -9.82214 3 | 90.7848 158.64 72 3.44429 -12.7573 4 | 91.1241 158.8 73 3.76856 -13.9774 5 | 90.9513 158.363 74 3.82661 -15.177 6 | 90.941 158.893 75 3.70376 -15.0228 7 | 91.302 158.797 76 3.57596 -14.5352 8 | 91.359 158.7 77 3.49635 -12.6779 9 | 91.2209 158.808 78 3.25188 -12.0806 10 | 91.369 158.782 79 3.14909 -11.9597 11 | 91.439 159.346 80 3.08912 -11.4354 12 | 91.4902 158.998 81 3.17703 -11.0262 13 | 91.9224 159.176 82 3.1659 -10.9337 14 | 91.8595 159.397 83 3.26815 -11.2728 15 | 91.9323 159.446 84 3.26248 -11.8075 16 | 92.4021 159.47 85 3.28727 -9.82404 17 | 92.2128 159.088 86 3.30305 -9.10594 18 | 92.3067 159.083 87 3.13526 -6.91413 19 | 91.5744 159.088 88 2.44119 -5.03172 20 | 90.7135 159.416 89 1.61309 -3.59364 21 | 90.9315 159.655 90 1.54544 -2.7493 22 | -------------------------------------------------------------------------------- /python/colloids/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import with_statement #for python 2.5, useless in 2.6 2 | -------------------------------------------------------------------------------- /python/colloids/clouds.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009 Mathieu Leocmach 3 | # 4 | # This file is part of Colloids. 5 | # 6 | # Colloids is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Colloids is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Colloids. If not, see . 18 | # 19 | import numpy as np 20 | import matplotlib.pyplot as plt 21 | from os.path import splitext 22 | from xml.dom.minidom import parse 23 | 24 | name2column = {'q4':0, 'q6':1, 'q8':2, 'q10':3, 'w4':4, 'w6':5, 'w8':6, 'w10':7} 25 | 26 | def draw_cloud(filename, plane=('q6', 'w6'), cloudType=('raw', 'raw'), timeAveraged=False): 27 | """ 28 | Draw a bond orientational order 2D histogram for various subsets of particles : 29 | all, crystalline, liquid, MRC0 30 | 31 | cloudType can be 'raw', 'cg' or 'surf' 32 | """ 33 | base, ext = splitext(filename) 34 | base, digits = base.split('_t') 35 | #load data 36 | #coords = np.loadtxt(filename, skiprows=2) 37 | if timeAveraged: 38 | cloudExt = '.boo' 39 | else: 40 | cloudExt = '.cloud' 41 | spaceCloud = np.loadtxt('_space_t'.join([base, digits])+cloudExt) 42 | #keep only the particles having data (inside) 43 | inside2 = np.where(spaceCloud[:,name2column['q6']]>0) 44 | cloud = np.loadtxt('_t'.join([base, digits])+cloudExt)[inside2] 45 | spaceCloud = spaceCloud[inside2] 46 | surfCloud = np.loadtxt('_surf_t'.join([base, digits])+cloudExt)[inside2] 47 | #coords = coords[inside2] 48 | subsets = { 49 | 'all':np.arange(cloud.shape[0]), 50 | 'liquid':np.where(spaceCloud[:,name2column['q6']]<0.25)[0], 51 | 'crystal':np.where(spaceCloud[:,name2column['q6']]>0.35)[0], 52 | 'MRCO':np.where(np.bitwise_and( 53 | spaceCloud[:,name2column['q6']]<0.35, 54 | spaceCloud[:,name2column['q6']]>0.25 55 | ))[0], 56 | 'FCC':np.where(np.bitwise_and( 57 | spaceCloud[:,name2column['q6']]>0.35, 58 | spaceCloud[:,name2column['w4']]<0 59 | ))[0], 60 | 'HCP':np.where(np.bitwise_and( 61 | spaceCloud[:,name2column['q6']]>0.35, 62 | spaceCloud[:,name2column['w4']]>0 63 | ))[0] 64 | } 65 | cloudTypes = { 66 | 'raw': cloud, 67 | 'cg': spaceCloud, 68 | 'surf': surfCloud 69 | } 70 | x = cloudTypes[cloudType[0]][:, name2column[plane[0]]] 71 | y = cloudTypes[cloudType[1]][:, name2column[plane[1]]] 72 | ranges = [[min([0, x.min()]), x.max()],[min([0, y.min()]), y.max()]] 73 | 74 | i=230 75 | for name, sel in subsets.iteritems(): 76 | if(len(sel)>0): 77 | H, xedges, yedges = np.histogram2d(x[sel], y[sel], bins=[100,100], range=ranges) 78 | else: 79 | H=np.zeros((100,100)) 80 | i+=1 81 | plt.subplot(i).set_aspect('equal') 82 | plt.imshow( 83 | np.log(np.rot90(H)/H.max()+1)*255, 84 | extent=ranges[0]+ranges[1], 85 | aspect='auto' 86 | ) 87 | #plt.axis(ranges[0]+ranges[1]) 88 | plt.xlabel(plane[0]) 89 | plt.ylabel(plane[1]) 90 | plt.title(name) 91 | plt.show() 92 | -------------------------------------------------------------------------------- /python/colloids/colors.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import numexpr 3 | 4 | def lab2rgb(im): 5 | l, a, b = np.dsplit(im, 3) 6 | y = numexpr.evaluate('(l + 16) / 116.0') 7 | x = numexpr.evaluate('a/500.0 + y') 8 | z = numexpr.evaluate('y - b/200.0') 9 | xyz = numexpr.evaluate( 10 | 'where(y**3>0.008856, y**3, (y - 16.0 / 116.0) / 7.787)*ref/100', 11 | { 12 | 'y':np.dstack((x,y,z)), 13 | 'ref': np.array([[[95.047, 100, 108.883]]]), #Observer= 2 deg Illuminant= D65 14 | } 15 | ) 16 | rgb = np.inner(xyz, np.array([ 17 | [3.2406, -1.5372, -0.4986], 18 | [-0.9689, 1.8758, 0.0415], 19 | [0.0557, -0.2040, 1.0570] 20 | ])) 21 | rgb = numexpr.evaluate('where(rgb > 0.0031308, 1.055 * rgb**(1/2.4) - 0.055, 12.92 * rgb)') 22 | #clip colors 23 | return np.minimum(np.maximum(rgb, 0), 1) 24 | 25 | def msh2rgb(im): 26 | m, s, h = np.dsplit(im, 3) 27 | l = numexpr.evaluate('m * cos(s)') 28 | a = numexpr.evaluate('m * sin(s) * cos(h)') 29 | b = numexpr.evaluate('m * sin(s) * sin(h)') 30 | return lab2rgb(np.dstack((l,a,b))) 31 | 32 | def colorscale(im, centre=88, extrema=80): 33 | """Take real values from 0 to 1 and return rgb colors on the diverging color scale blue-white-red. Taken from Paraview.""" 34 | x = np.mod(im, 1) 35 | m = numexpr.evaluate('2*(extrema-centre)*abs(x-0.5)+centre') 36 | #m = numexpr.evaluate('88-16*abs(x-0.5)') 37 | s = numexpr.evaluate('1.08 * 2*abs(0.5-x)') 38 | h = numexpr.evaluate('where(x<0.5, -1.1 - 2*x*0.561, 1.061 - 2*(x-0.5)*0.561)') 39 | return msh2rgb(np.dstack((m,s,h))) 40 | 41 | -------------------------------------------------------------------------------- /python/colloids/count_nuclei.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from colloids import track 3 | from scipy.misc import imsave, imshow, imread 4 | import sys, itertools, re 5 | from os.path import split,join,isfile 6 | 7 | if len(sys.argv) >1: 8 | filename = sys.argv[1] 9 | else: 10 | while(True): 11 | filename = raw_input("filename --> ") 12 | if isfile(filename): 13 | break 14 | else: 15 | print '"%s" is not an existing file' % filename 16 | 17 | m = re.match('(.*)_([0-9]*)(.*)', filename) 18 | assert m is not None, '"%s" do not match pattern' % filename 19 | pattern = m.group(1)+'_%'+('0%dd'%len(m.group(2)))+(''.join(m.groups()[2:])) 20 | path, name = split(m.group(1)) 21 | outpattern = join(path,'treated_'+name)+'_%'+('0%dd'%len(m.group(2)))+(''.join(m.groups()[2:])) 22 | 23 | im = imread(filename) 24 | cent = np.zeros_like(im) 25 | finder = track.MultiscaleBlobFinder(im.shape, nbOctaves=100) 26 | 27 | f = open(m.group(1)+'.nb', 'w') 28 | 29 | for t in itertools.count(): 30 | if not isfile(pattern%t): 31 | break 32 | im = imread(pattern%t) 33 | centers = finder(im, Octave0=False, removeOverlap=False) 34 | centers = centers[centers[:,-1]<-1] 35 | f.write('%d\n'%len(centers)) 36 | f.flush() 37 | cent.fill(0) 38 | for (ym,xm), (yM, xM) in zip(np.maximum(0, centers[:,:2]-centers[:,2][:,None]), np.minimum(centers[:,:2]+centers[:,2][:,None]+1, im.shape[::-1])): 39 | cent[xm:xM,ym:yM] += 50 40 | imsave(outpattern%t, np.dstack((im, cent, cent))) 41 | f.close() 42 | 43 | -------------------------------------------------------------------------------- /python/colloids/cython/periodic.pyx: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | cimport numpy as np 3 | cimport cython 4 | 5 | @cython.boundscheck(False) # turn off bounds-checking for entire function 6 | @cython.wraparound(False) # turn off negative index wrapping for entire function 7 | @cython.cdivision(True) # turn off division by zero checking for entire function 8 | def periodify( 9 | np.ndarray[np.float64_t, ndim=2] u, 10 | np.ndarray[np.float64_t, ndim=2] v, 11 | periods=None 12 | ): 13 | assert u.shape[0] == v.shape[0] 14 | assert u.shape[1] == v.shape[1] 15 | #cdef np.ndarray[np.float64_t, ndim=2] diff = v - u 16 | if periods is None: 17 | return v - u 18 | assert len(periods) == u.shape[1] 19 | cdef np.ndarray[np.float64_t, ndim=2] diff = np.zeros_like(u) 20 | #ensures the largest coordinate is smaller than half a period 21 | cdef np.ndarray[np.float64_t, ndim=1] pers = np.array(periods) 22 | cdef np.ndarray[np.float64_t, ndim=1] half = 0.5*np.array(periods) 23 | cdef int i,j 24 | cdef float d,h,p 25 | for i in range(diff.shape[0]): 26 | for j in range(diff.shape[1]): 27 | d = v[i,j] - u[i,j] 28 | h = half[j] 29 | p = pers[j] 30 | while d > h: 31 | d -= p 32 | while d < -h: 33 | d += p 34 | diff[i,j] = d 35 | return diff 36 | -------------------------------------------------------------------------------- /python/colloids/cython/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | from Cython.Build import cythonize 3 | 4 | setup( 5 | name = 'Colloid toolkit', 6 | ext_modules = cythonize("periodic.pyx"), 7 | ) 8 | -------------------------------------------------------------------------------- /python/colloids/cython/structure_factor.pyx: -------------------------------------------------------------------------------- 1 | cimport cython 2 | import numpy as np 3 | cimport numpy as np 4 | from libc.math cimport floor, sqrt, sin, M_PI 5 | cdef extern from "complex.h": 6 | double complex cexp(double complex) 7 | double creal(double complex); 8 | double cimag(double complex); 9 | 10 | ctypedef np.int_t DTYPE_t 11 | 12 | @cython.boundscheck(False) 13 | cdef DTYPE_t generate_kvec3D(int nk, np.ndarray[DTYPE_t, ndim=2] kvectors): 14 | """Generate the indices of the 3D wavevectors in a cubic box""" 15 | cdef DTYPE_t maxNvec = kvectors.shape[0] 16 | assert maxNvec%3 == 0 17 | cdef int i,j,k 18 | cdef DTYPE_t nvec = 0 19 | for i in range(nk): 20 | if nvec >= maxNvec: break 21 | #for j in range(int(sqrt(nk*nk-i*i))): 22 | j=0 23 | while j**2 < nk**2 - i**2: 24 | if nvec >= maxNvec: break 25 | k = int(sqrt(nk*nk-i*i-j*j)) 26 | #if k != int(k): continue 27 | kvectors[nvec,0] = i 28 | kvectors[nvec,1] = j 29 | kvectors[nvec,2] = k 30 | kvectors[nvec+1,0] = j 31 | kvectors[nvec+1,1] = k 32 | kvectors[nvec+1,2] = i 33 | kvectors[nvec+2,0] = k 34 | kvectors[nvec+2,1] = i 35 | kvectors[nvec+2,2] = j 36 | nvec += 3 37 | j += 1 38 | return nvec 39 | 40 | @cython.boundscheck(False) 41 | cdef DTYPE_t generate_kvec2D(int nk, np.ndarray[DTYPE_t, ndim=2] kvectors): 42 | """Generate the indices of the 2D wavevectors in a square box""" 43 | cdef DTYPE_t maxNvec = kvectors.shape[0] 44 | cdef double M = 0.5*M_PI/maxNvec 45 | cdef int i,j,u 46 | cdef DTYPE_t nvec = 0 47 | 48 | for u in range(maxNvec/2): 49 | i = int(nk * sin(M * u)) 50 | if nvec >0 and kvectors[nvec-1, 0] == i: 51 | continue 52 | j = int(sqrt(nk**2 - i**2)) 53 | kvectors[nvec,0] = i 54 | kvectors[nvec,1] = j 55 | kvectors[nvec+1,0] = j 56 | kvectors[nvec+1,1] = i 57 | nvec += 2 58 | 59 | return nvec 60 | 61 | def get_Sq(np.ndarray[np.float64_t, ndim=2] pos, int Nbins, double L=203.0, DTYPE_t maxNvec=30, np.ndarray[double complex, ndim=1]field=None): 62 | """Structure factor of the positions in a square or cubic box of size L.""" 63 | #implementation without parallelism, 64 | #within 10% of previous scipy.weave implementation (parallelism disabled) 65 | if pos.shape[1] ==2: 66 | generate_kvec = generate_kvec2D 67 | elif pos.shape[1] == 3: 68 | generate_kvec = generate_kvec3D 69 | else: 70 | raise NotImplementedError("generation of k-vectors in {} dimensions is not implemented".format(pos.shape[1])) 71 | if field is None: 72 | field = np.ones(pos.shape[0], np.complex128) 73 | assert field.shape[0] == pos.shape[0] 74 | cdef double complex prod, sum_rho, e 75 | cdef DTYPE_t i, j, k, nk, kv, nvec 76 | cdef double p 77 | cdef np.ndarray[DTYPE_t, ndim=2] kvectors= np.zeros((maxNvec, pos.shape[1]), dtype=int) 78 | cdef np.ndarray[double, ndim=1] Sq = np.zeros(Nbins) 79 | #cache the complex exponential caculations 80 | cdef np.ndarray[double complex, ndim=3] cache = np.ones([Nbins, pos.shape[0], pos.shape[1]], np.complex128) 81 | for i in range(pos.shape[0]): 82 | for j in range(pos.shape[1]): 83 | p = pos[i,j] 84 | e = cexp(2j*M_PI/L * p) 85 | for nk in range(1,Sq.shape[0]): 86 | cache[nk, i, j] = cache[nk-1, i, j] * e 87 | for nk in range(1,Sq.shape[0]): 88 | #generate the k-vectors 89 | nvec = generate_kvec(nk, kvectors) 90 | for k in range(nvec): 91 | sum_rho = 0j 92 | for i in range(pos.shape[0]): 93 | prod = field[i] 94 | for j in range(pos.shape[1]): 95 | kv = kvectors[k,j] 96 | #random access to cache 97 | prod *= cache[kv, i, j] 98 | sum_rho += prod 99 | Sq[nk] += creal(sum_rho)**2 + cimag(sum_rho)**2 100 | Sq[nk] /= nvec 101 | return Sq / pos.shape[0] 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /python/colloids/ddm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright 2015 Mathieu Leocmach 5 | # 6 | # This file is part of Colloids. 7 | # 8 | # Colloids is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Colloids is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Colloids. If not, see . 20 | # 21 | 22 | # Implementation of the basics of Differential Dynamics Microscopy 23 | # Cerbino, R. & Trappe, V. Differential dynamic microscopy: Probing wave vector dependent dynamics with a microscope. Phys. Rev. Lett. 100, 1–4 (2008). 24 | 25 | import numpy as np 26 | from matplotlib.image import imread 27 | import numexpr 28 | 29 | def readImages(path, N, t0=1): 30 | """Read N successive images using the given and stock them in a numpy array 31 | NxHxW (image shape is HxW) of type np.uint8. 32 | The path is a string to be formatted like 'directory/images_{:06d}.tif' 33 | so that path.format(124) -> 'directory/images_000124.tif'. 34 | """ 35 | #get the images shape while checking that the last image do exist 36 | H, W = imread(path.format(N-1+t0)).shape[:-1] #imread makes 4 channels out of one 37 | images = np.zeros([N, H, W], np.uint8) 38 | for t in range(N): 39 | images[t] = imread(path.format(t+t0))[:,:,0] 40 | return images 41 | 42 | 43 | def spectreDiff(im0, im1): 44 | """Compute the squared modulus of the 2D Fourier Transform of the difference between im0 and im1""" 45 | return numexpr.evaluate( 46 | 'real(abs(f))**2', 47 | {'f': np.fft.fft2(im1-im0.astype(float))} 48 | ) 49 | 50 | class RadialAverager(object): 51 | """Radial average of a 2D array centred on (0,0), like the result of fft2d.""" 52 | def __init__(self, shape): 53 | assert len(shape)==2 54 | self.dists = np.sqrt(np.fft.fftfreq(shape[0])[:,None]**2 + np.fft.fftfreq(shape[1])[None,:]**2) 55 | self.bins = np.fft.fftfreq(max(shape))[:max(shape)/2] 56 | self.hd = np.histogram(self.dists, self.bins)[0] 57 | 58 | def __call__(self, im): 59 | assert im.shape == self.dists.shape 60 | hw = np.histogram(self.dists, self.bins, weights=im)[0] 61 | return hw/self.hd 62 | 63 | def radialAverage(im): 64 | """Radial average of a 2D array centred on (0,0), like the result of fft2d.""" 65 | dists = np.sqrt(np.fft.fftfreq(im.shape[0])[:,None]**2 + np.fft.fftfreq(im.shape[1])[None,:]**2) 66 | bins = np.fft.fftfreq(max(im.shape))[:max(im.shape)/2] 67 | hd = np.histogram(dists, bins)[0] 68 | hw = np.histogram(dists, bins, weights=im)[0] 69 | return hw/hd 70 | 71 | def timeAveraged(images, dt, navmax=100): 72 | """Does at most navmax spectreDiff on regularly spaced couples of images. 73 | Separation within couple is dt.""" 74 | result = np.zeros(images.shape[1:]) 75 | step = max([(len(images)-dt)/navmax, 1]) 76 | couples = np.arange(0, len(images)-dt, step) 77 | #print step, len(couples) 78 | for t in couples: 79 | result += spectreDiff(images[t], images[t+dt]) 80 | return result / len(couples) 81 | 82 | def logSpaced(L, num=50): 83 | """Generate an array of log spaced integers smaller than L""" 84 | return np.unique(np.logspace( 85 | start=0, stop=np.log(L)/np.log(2), 86 | num=num, base=2, endpoint=False 87 | ).astype(int)) 88 | 89 | def ddm(images, navmax=100, num=50): 90 | """Does timeAveraged and radialAverage for log-spaced time intervals. 91 | Returns (intervals, ddm)""" 92 | dts = logSpaced(len(images), num) 93 | ra = RadialAverager(images.shape[1:]) 94 | D = np.zeros((len(dts), len(ra.hd))) 95 | for i, dt in enumerate(dts): 96 | D[i] = ra(timeAveraged(images, dt, navmax)) 97 | return dts, D 98 | -------------------------------------------------------------------------------- /python/colloids/depreciated/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/python/colloids/depreciated/__init__.py -------------------------------------------------------------------------------- /python/colloids/dillute_raw.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/python/colloids/dillute_raw.npy -------------------------------------------------------------------------------- /python/colloids/displ2D.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # 3 | # Copyright 2009 Mathieu Leocmach 4 | # 5 | # This file is part of Colloids. 6 | # 7 | # Colloids is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Colloids is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Colloids. If not, see . 19 | # 20 | import lif 21 | import sys 22 | from os.path import splitext,isfile 23 | from numpy import savetxt 24 | 25 | if len(sys.argv) >1: 26 | filename = sys.argv[1] 27 | else: 28 | while(True): 29 | filename = raw_input("filename --> ") 30 | if isfile(filename): 31 | break 32 | else: 33 | print '"%s" is not an existing file' % filename 34 | 35 | reader = lif.Reader(filename) 36 | for serie in reader.getSeries(): 37 | if serie.getNbFrames() > 1: 38 | displ = serie.getDisplacements2D() 39 | savetxt( 40 | splitext(filename)[0]+"_"+serie.getName()+".displ", 41 | displ, 42 | fmt='%1d', 43 | delimiter='\t' 44 | ) 45 | -------------------------------------------------------------------------------- /python/colloids/h52traj.py: -------------------------------------------------------------------------------- 1 | import sys, os, os.path, argparse, shutil 2 | import numpy as np 3 | from pandas import DataFrame 4 | import trackpy as tp 5 | from colloids import experiment as xp 6 | from colloids.progressbar import ProgressBar 7 | from colloids.particles import Linker 8 | 9 | if __name__ == '__main__': 10 | parser = argparse.ArgumentParser(description='Convert a HDF5 format compatible with trackpy.PandasHDFStoreSingleNode to coordinates and trajectory data.') 11 | parser.add_argument('h5name', help='HDF5 file name') 12 | parser.add_argument('--out', help='The folder where to save the data. By default the same name as HDF5 file, without extension.') 13 | args = parser.parse_args() 14 | h5name = args.h5name 15 | print(h5name) 16 | 17 | if args.out is None: 18 | args.out = os.path.splitext(h5name)[0] 19 | print('to %s'%args.out) 20 | os.mkdir(args.out) 21 | basename = os.path.join(args.out, os.path.split(os.path.basename(h5name))[0]) 22 | 23 | with tp.PandasHDFStoreSingleNode(h5name) as s: 24 | nbzeros = len('%d'%(len(s)-1)) 25 | datfile = +'_t%0{:d}d.dat'.format(nbzeros) 26 | p2trfile = +'_t%0{:d}d.p2tr'.format(nbzeros) 27 | pro = ProgressBar(len(s)) 28 | for t, frame in s: 29 | pos = np.vstack((np.zeros(2,3), frame.as_matrix(['x','y','z']))) 30 | pos[0] = 1, len(pos)-2, 1 31 | np.savetxt(datfile%t, pos, fmt='%g') 32 | np.savetxt(p2trfile%t, frame.asmatrix(['particle'], fmt='%d') 33 | #if t==0: 34 | # linker = Linker(len(frame)) 35 | #else: 36 | # linker.loadFrame(frame.asmatrix(['particle']) 37 | pro.animate(t) 38 | #TODO save the linker to a traj file 39 | 40 | -------------------------------------------------------------------------------- /python/colloids/lif2vtk.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # 3 | # Copyright 2009 Mathieu Leocmach 4 | # 5 | # This file is part of Colloids. 6 | # 7 | # Colloids is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Colloids is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Colloids. If not, see . 19 | # 20 | import lif 21 | import sys 22 | from os.path import splitext,isfile 23 | 24 | if len(sys.argv) >1: 25 | filename = sys.argv[1] 26 | else: 27 | while(True): 28 | filename = raw_input("filename --> ") 29 | if isfile(filename): 30 | break 31 | else: 32 | print '"%s" is not an existing file' % filename 33 | 34 | reader = lif.Reader(filename) 35 | hout = open(splitext(filename)[0]+'.xml', 'w') 36 | reader.xmlHeader.writexml(hout) 37 | hout.close() 38 | 39 | if len(sys.argv)>2: 40 | serie = reader.chooseSerie(int(sys.argv[1])) 41 | else: 42 | serie = reader.chooseSerie() 43 | #geometrical information 44 | shape = serie.getFrameShape() 45 | extent = [serie.getVoxelSize(d+1)*l for d,l in enumerate(shape)] 46 | flatdims = 3-len(shape) 47 | nbpixels = serie.getNbPixelsPerFrame() 48 | nbchannels = max(1, len(serie.getChannels())) 49 | 50 | nbdigits = len('%s'%serie.getNbFrames()) 51 | output = u'%s_%s_t%%0%dd.vtk' %(splitext(filename)[0], serie.getName(), nbdigits) 52 | 53 | serie.f.seek(serie.getOffset()) 54 | for t in range(serie.getNbFrames()): 55 | out = open(output%t, 'wb') 56 | out.write('# vtk DataFile Version 2.0\n') 57 | out.write('%s %s\n' % (reader.getName(), serie.getName())) 58 | out.write('BINARY\nDATASET STRUCTURED_POINTS\n') 59 | out.write('DIMENSIONS %d %d %d\nORIGIN 0 0 0\n' % tuple(shape+flatdims*[1])) 60 | out.write( 61 | 'SPACING %g %g %g\n' % tuple( 62 | [serie.getVoxelSize(d+1) for d in range(len(shape))]+flatdims*[1] 63 | ) 64 | ) 65 | out.write('POINT_DATA %d\n' % nbpixels) 66 | #out.write('SCALARS intensity unsigned_char %d\n' % nbchannels) 67 | #out.write('LOOKUP_TABLE default\n') 68 | out.write('COLOR_SCALARS intensity %d\n' % nbchannels) 69 | out.write(serie.f.read(nbpixels*nbchannels)) 70 | out.close() 71 | -------------------------------------------------------------------------------- /python/colloids/lifTest.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # 3 | # Copyright 2009 Mathieu Leocmach 4 | # 5 | # This file is part of Colloids. 6 | # 7 | # Colloids is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Colloids is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Colloids. If not, see . 19 | # 20 | import sys 21 | from os.path import splitext,isfile 22 | import lif 23 | import Image 24 | 25 | #reader = lif.Reader("D:\Users\ishizaka\Documents\dataMathieu\Tsuru11dm_phi=52.53_J36.lif") 26 | if len(sys.argv) >1: 27 | filename = sys.argv[1] 28 | if not isfile(filename): 29 | print "%s is not an existing file" % filename 30 | exit 31 | else: 32 | while(True): 33 | filename = raw_input("filename --> ") 34 | if isfile(filename): 35 | break 36 | else: 37 | print "%s is not an existing file" % filename 38 | 39 | reader = lif.Reader(filename) 40 | 41 | #export of the XML header 42 | fHeader = open(splitext(filename)[0]+"_header.xml","w") 43 | reader.xmlHeader.writexml(fHeader) 44 | fHeader.close() 45 | 46 | #Content short description 47 | serie = reader.chooseSerie() 48 | print "%s : %i frames X %i pixels per frames" % (serie.getName(),serie.getNbFrames(),serie.getNbPixelsPerFrame()) 49 | 50 | #just getting a 2D slice 51 | serie.get2DImage().show() 52 | 53 | #loading a full time step into a numpy array 54 | a = serie.getFrame(0) 55 | #extracting the slice Z==0 into an image 56 | if len(serie.getDimensions()) >2: 57 | im = Image.fromarray(a[0,:,:]) 58 | else: 59 | im = Image.fromarray(a) 60 | im.show() 61 | -------------------------------------------------------------------------------- /python/colloids/microrheology.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2013 Mathieu Leocmach 3 | # 4 | # This file is part of Colloids. 5 | # 6 | # Colloids is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Colloids is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Colloids. If not, see . 18 | # 19 | 20 | import numpy as np 21 | import scipy.constants as const 22 | from scipy.special import gamma 23 | import warnings 24 | 25 | def log_msd_vs_tau(tau,msd,maxtime=None): 26 | """ 27 | Converts MSD and tau vectors in one 2 column matrix spaced 28 | logarithmically in tau, roughly 16 points per decade. 29 | 30 | INPUTS 31 | 32 | tau - the tau vector 33 | msd - the MSD vector 34 | maxtime - the maximum time to consider in second 35 | 36 | OUTPUTS 37 | 38 | msdtau - a 2 column matrix, with tau in the first column and the MSD in 39 | the second column. 40 | """ 41 | timestep = tau[tau>0].min() 42 | if maxtime is None: 43 | maxtime = (tau>0).sum() 44 | maxT = np.log(maxtime)/np.log(1.15) 45 | dt = np.unique(np.round(1.15**np.arange(maxT)).astype(int))-1 46 | w = dt < maxtime 47 | ndt = w.sum() 48 | if ndt > 0: 49 | dt = dt[w] 50 | else: 51 | raise ValueError('Invalid maximum dt!') 52 | return np.column_stack((tau[tau>0][dt], msd[tau>0][dt])) 53 | 54 | 55 | def logderive(x,f,width): 56 | """A special purpose routine for finding the first and second logarithmic derivatives of slowly varying, but noisy data. It returns a smoother version of 'f' and its first and second log derivative.""" 57 | assert len(x)==len(f) 58 | lx = np.log(x) 59 | ly = np.log(f) 60 | f2 = np.zeros_like(f) 61 | df = np.zeros_like(f) 62 | ddf = np.zeros_like(f) 63 | 64 | for i, u in enumerate(lx): 65 | #Data are unequally spaced, so we cannot use a simple gaussian_filter 66 | w = np.exp(-(lx-u)**2 / (2*width**2)) 67 | #truncate the Gaussian, run faster 68 | ww = w > 0.03 69 | #polynomial fit weighted by the Gaussian. 70 | p = np.poly1d(np.polyfit(lx[ww], ly[ww], 2, w=w[ww])) 71 | f2[i] = np.exp(p(u)) 72 | df[i] = p.deriv(1)(u) 73 | ddf[i] = p.deriv(2)(u) 74 | return f2, df, ddf 75 | 76 | 77 | 78 | def msd2G(dt, msd, a, T, dim=3, clip=0.03, width=0.7): 79 | """One particle microrheology. Returns omega (1/s), G (Pa) 80 | 81 | Keyword arguments: 82 | dt -- in seconds 83 | msd -- in microns^2 84 | a -- radius in microns 85 | T -- in Kelvin 86 | dim -- the dimensionality of the data 87 | clip -- a fraction of G(s) below which G'(w) and G"(w) are meaningless (see NOTES) 88 | width -- the width of the gaussian that is used for the polyfit (see Notes below) 89 | 90 | NOTES: 91 | It needs more than a 7-8 points per decade of time/frequency 92 | and really hates noise and long-wavelength ripples in the data. 93 | 94 | G'(w) and G"(w) are clipped at 0.03x G(s) as they are almost 95 | certainly meaningless below that point unless the data is 96 | *extremely* clean. Set 'clip' to less than 0.03 to see more. 97 | See Tom Mason's paper: PRL *79*, 3284, (1997) for details. 98 | 99 | set the width to something bigger for noisy data, ok if the data 100 | is very weakly curved. recommended starting value: 0.7 101 | 102 | This function is the translation of the IDL implementation by John C. Crocker in 1999 103 | """ 104 | assert len(dt) == len(msd) 105 | #convert the inputs in meters - Kilograms - Seconds 106 | am = a * 1e-6 107 | omega = 1./ dt 108 | msdm = msd * 1e-12 109 | C = dim * const.k * T / (3 * np.pi * am) 110 | 111 | #use 2nd order local formula for G(s)-- good to 1% of G(s) 112 | m, d, dd = logderive(dt, msdm, width) 113 | Gs = C / (m * gamma(1+d) * (1 + dd/2)) 114 | 115 | #use 2nd order local formula for G'(w),G"(w)-- good to 2% of G(w) 116 | g, da, dda = logderive(omega, Gs, width) 117 | foo = (np.pi/2 - 1) * (da + 1j*(1-da)) * dda 118 | G = g / (1+dda) * (np.exp(0.5j * np.pi * da) - foo) 119 | 120 | 121 | if (np.abs(dd).max() > 0.15) or (np.abs(dda).max() > 0.15): #original value: 0.15 122 | warnings.warn('High curvature in data, moduli may be unreliable!') 123 | 124 | #clip off the suspicious (i.e. unreliable) data 125 | w = G.real < Gs*clip 126 | if w.sum() > 0: 127 | G.real[w]=0 128 | w = G.imag < Gs*clip 129 | if w.sum() > 0: 130 | G.imag[w]=0 131 | 132 | return omega, G 133 | -------------------------------------------------------------------------------- /python/colloids/notebooks/droplets.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/python/colloids/notebooks/droplets.jpg -------------------------------------------------------------------------------- /python/colloids/progressbar.py: -------------------------------------------------------------------------------- 1 | #Code from https://github.com/ipython/ipython/issues/1527/ 2 | 3 | from __future__ import print_function #for python 2.x 4 | import sys, time 5 | try: 6 | from IPython.core.display import clear_output 7 | have_ipython = True 8 | try: 9 | from ipykernel.zmqshell import ZMQInteractiveShell 10 | from ipywidgets import FloatProgress 11 | from IPython.display import display 12 | in_notebook = isinstance(get_ipython(), ZMQInteractiveShell) 13 | except (ImportError, NameError): 14 | in_notebook = False 15 | except ImportError: 16 | have_ipython = False 17 | 18 | class ProgressBar: 19 | """Displays the progression of N steps known in advance (i.e. a loop of N iterations). Example of use: 20 | pro = ProgressBar(5000) 21 | for i in range(5000): 22 | #do something 23 | pro.animate(i) 24 | """ 25 | def __init__(self, iterations): 26 | self.iterations = iterations 27 | self.prog_bar = '[]' 28 | self.fill_char = '*' 29 | self.width = 40 30 | self.__update_amount(0) 31 | if have_ipython: 32 | if(in_notebook): 33 | self.animate = self.animate_notebook 34 | self.fp = FloatProgress(min=0, max=self.iterations) 35 | display(self.fp) 36 | else: 37 | self.animate = self.animate_ipython 38 | else: 39 | self.animate = self.animate_noipython 40 | 41 | def animate_ipython(self, iter): 42 | try: 43 | clear_output() 44 | except Exception: 45 | # terminal IPython has no clear_output 46 | pass 47 | print(self, end='\r') 48 | sys.stdout.flush() 49 | self.update_iteration(iter + 1) 50 | 51 | def animate_notebook(self, i): 52 | self.fp.value = i 53 | 54 | def update_iteration(self, elapsed_iter): 55 | self.__update_amount((elapsed_iter / float(self.iterations)) * 100.0) 56 | self.prog_bar += ' %d of %s complete' % (elapsed_iter, self.iterations) 57 | 58 | def __update_amount(self, new_amount): 59 | percent_done = int(round((new_amount / 100.0) * 100.0)) 60 | all_full = self.width - 2 61 | num_hashes = int(round((percent_done / 100.0) * all_full)) 62 | self.prog_bar = '[' + self.fill_char * num_hashes + ' ' * (all_full - num_hashes) + ']' 63 | pct_place = (len(self.prog_bar) // 2) - len(str(percent_done)) 64 | pct_string = '%d%%' % percent_done 65 | self.prog_bar = self.prog_bar[0:pct_place] + \ 66 | (pct_string + self.prog_bar[pct_place + len(pct_string):]) 67 | 68 | def __str__(self): 69 | return str(self.prog_bar) 70 | -------------------------------------------------------------------------------- /python/colloids/spectrum.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from scipy.misc import imshow, imread 3 | import sys, itertools, re 4 | from os.path import split,join,isfile 5 | import numexpr 6 | 7 | if len(sys.argv) >1: 8 | filename = sys.argv[1] 9 | else: 10 | while(True): 11 | filename = raw_input("filename --> ") 12 | if isfile(filename): 13 | break 14 | else: 15 | print '"%s" is not an existing file' % filename 16 | 17 | m = re.match('(.*)_([0-9]*)(.*)', filename) 18 | assert m is not None, '"%s" do not match pattern' % filename 19 | pattern = m.group(1)+'_%'+('0%dd'%len(m.group(2)))+(''.join(m.groups()[2:])) 20 | path, name = split(m.group(1)) 21 | outpattern = join(path,'spectrum_'+name)+'_%'+('0%dd'%len(m.group(2)))+'.dat' 22 | 23 | im = imread(filename) 24 | shape = im.shape 25 | wavenumbers = map(np.fft.fftfreq, shape) 26 | dists = numexpr.evaluate('sqrt(qx**2+qy**2)', { 27 | 'qx':wavenumbers[0][:,None], 28 | 'qy':wavenumbers[1][None,:shape[-1]/2+1] 29 | }) 30 | nbq, qs = np.histogram(dists.ravel(), wavenumbers[0][:len(wavenumbers[0])/2]) 31 | ws = map(np.hamming, shape) 32 | 33 | for t in itertools.count(): 34 | if not isfile(pattern%t): 35 | break 36 | im = imread(pattern%t) 37 | im = im - im.mean() 38 | for d, w in enumerate(ws): 39 | im *= w[tuple([None]*d + [slice(None)] + [None]*(im.ndim-d-1))] 40 | spectrum = numexpr.evaluate( 41 | 'abs(f).real**2', 42 | {'f': np.fft.rfftn(im)} 43 | ) 44 | Sq = np.histogram(dists.ravel(), qs, weights=spectrum.ravel())[0] 45 | Sq[nbq>0] /= nbq[nbq>0] 46 | np.savetxt(outpattern%t, Sq) 47 | 48 | -------------------------------------------------------------------------------- /python/colloids/test_particles.py: -------------------------------------------------------------------------------- 1 | from particles import * 2 | import unittest 3 | import numpy.testing as npt 4 | 5 | 6 | class TestLinker(unittest.TestCase): 7 | def test_one(self): 8 | #a single particle at t=0 9 | linker = Linker(1) 10 | self.assertEqual(len(linker.pos2tr), 1) 11 | npt.assert_equal(linker.pos2tr[-1], [0]) 12 | self.assertEqual(len(linker.tr2pos), 1) 13 | self.assertListEqual(linker.tr2pos[0], [0]) 14 | self.assertListEqual(linker.trajstart, [0]) 15 | self.assertListEqual(linker.nbtrajs, [1]) 16 | #no particles at t=1 17 | pairs = np.zeros([0,2],int) 18 | distances = np.zeros([0]) 19 | linker.addFrame(0, pairs, distances) 20 | self.assertEqual(len(linker.pos2tr), 2) 21 | self.assertEqual(len(linker.pos2tr[-1]), 0) 22 | self.assertEqual(len(linker.tr2pos), 1) 23 | self.assertListEqual(linker.tr2pos[0], [0]) 24 | self.assertListEqual(linker.trajstart, [0]) 25 | self.assertListEqual(linker.nbtrajs, [1,1]) 26 | #the particle is back a t=2 27 | linker.addFrame(1, pairs, distances) 28 | self.assertEqual(len(linker.pos2tr), 3) 29 | npt.assert_equal(linker.pos2tr[-1], [1]) 30 | self.assertEqual(len(linker.tr2pos), 2) 31 | self.assertListEqual(linker.tr2pos, [[0],[0]]) 32 | self.assertListEqual(linker.trajstart, [0, 2]) 33 | self.assertListEqual(linker.nbtrajs, [1,1,2]) 34 | #Actually the particle at t=0 and the one at t=2 where the same 35 | pairs = np.array([[0, 0]], int) 36 | distances = np.zeros([1]) 37 | linker.update(pairs, distances) 38 | self.assertEqual(len(linker.pos2tr), 3) 39 | npt.assert_equal(linker.pos2tr[0], [0]) 40 | npt.assert_equal(linker.pos2tr[1], [0]) 41 | npt.assert_equal(linker.pos2tr[2], [0]) 42 | self.assertEqual(len(linker.tr2pos), 1) 43 | self.assertListEqual(linker.tr2pos[0], [0,0,0]) 44 | self.assertListEqual(linker.trajstart, [0]) 45 | self.assertListEqual(linker.nbtrajs, [1,1,1]) 46 | #no particles at t=3 47 | pairs = np.zeros([0,2],int) 48 | distances = np.zeros([0]) 49 | linker.addFrame(0, pairs, distances) 50 | self.assertEqual(len(linker.pos2tr), 4) 51 | self.assertEqual(len(linker.pos2tr[-1]), 0) 52 | self.assertEqual(len(linker.tr2pos), 1) 53 | self.assertListEqual(linker.tr2pos[0], [0,0,0]) 54 | self.assertListEqual(linker.trajstart, [0]) 55 | self.assertListEqual(linker.nbtrajs, [1,1,1,1]) 56 | #two particles are back a t=4 57 | linker.addFrame(2, pairs, distances) 58 | self.assertEqual(len(linker.pos2tr), 5) 59 | npt.assert_equal(linker.pos2tr[-1], [1,2]) 60 | self.assertEqual(len(linker.tr2pos), 3) 61 | self.assertListEqual(linker.tr2pos, [[0,0,0],[0],[1]]) 62 | self.assertListEqual(linker.trajstart, [0, 4, 4]) 63 | self.assertListEqual(linker.nbtrajs, [1,1,1,1,3]) 64 | #Actually the particle at t=3 and the second one at t=4 where the same 65 | pairs = np.array([[0, 1]], int) 66 | distances = np.zeros([1]) 67 | linker.update(pairs, distances) 68 | self.assertEqual(len(linker.pos2tr), 5) 69 | npt.assert_equal(linker.pos2tr[0], [0]) 70 | npt.assert_equal(linker.pos2tr[1], [0]) 71 | npt.assert_equal(linker.pos2tr[2], [0]) 72 | npt.assert_equal(linker.pos2tr[3], [0]) 73 | npt.assert_equal(linker.pos2tr[4], [1,0]) 74 | self.assertEqual(len(linker.tr2pos), 2) 75 | self.assertListEqual(linker.tr2pos, [[0,0,0,0,1],[0]]) 76 | self.assertListEqual(linker.trajstart, [0,4]) 77 | self.assertListEqual(linker.nbtrajs, [1,1,1,1,2]) 78 | -------------------------------------------------------------------------------- /python/colloids/track_orange.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from colloids import track, particles 3 | from scipy.misc import imsave, imshow, imread 4 | import sys, itertools, re 5 | from os.path import split,join,isfile, splitext 6 | import Image 7 | 8 | def readTIFF16(path): 9 | """Read 16bits TIFF""" 10 | im = Image.open(path) 11 | out = np.fromstring( 12 | im.tostring(), 13 | np.uint8 14 | ).reshape(tuple(list(im.size)+[2])) 15 | return (np.array(out[:,:,0], np.uint16)<<8)+out[:,:,1] 16 | 17 | #read input file name 18 | if len(sys.argv) >1: 19 | filename = sys.argv[1] 20 | else: 21 | while(True): 22 | filename = raw_input("filename --> ") 23 | if isfile(filename): 24 | break 25 | else: 26 | print '"%s" is not an existing file' % filename 27 | 28 | #how is made the file series name template 29 | #the last groupe of digits afet a _ is supposed to be the time step 30 | m = re.match('(.*)_([0-9]*)(.*)', filename) 31 | assert m is not None, '"%s" do not match pattern' % filename 32 | pattern = m.group(1)+'_%'+('0%dd'%len(m.group(2)))+(''.join(m.groups()[2:])) 33 | path, name = split(m.group(1)) 34 | outpattern = join(path,'treated_'+name)+'_%'+('0%dd'%len(m.group(2)))+(''.join(m.groups()[2:])) 35 | 36 | #read the first image 37 | im = imread(filename) 38 | if im.ndim ==0: 39 | im = readTIFF16(filename) 40 | cent = np.zeros_like(im) 41 | finder = track.MultiscaleBlobFinder(im.shape, nbOctaves=100) 42 | 43 | 44 | 45 | for t in itertools.count(): 46 | if not isfile(pattern%t): 47 | break 48 | im = imread(pattern%t) 49 | if im.ndim ==0: 50 | im = readTIFF16(pattern%t) 51 | #localisation 52 | centers = finder(im, k=1.0,Octave0=False, removeOverlap=True, maxedge=100.) 53 | centers = centers[centers[:,-1]<-1] 54 | #output result image 55 | cent.fill(0) 56 | for (ym,xm), (yM, xM) in zip(np.maximum(0, centers[:,:2]-centers[:,2][:,None]), np.minimum(centers[:,:2]+centers[:,2][:,None]+1, im.shape[::-1])): 57 | cent[xm:xM,ym:yM] += 50/256.*im.max() 58 | imsave(outpattern%t, np.dstack((im, cent, cent))) 59 | #Trajectory linking 60 | if t==0: 61 | linker = particles.Linker(len(centers)) 62 | pos1 = centers 63 | else: 64 | pos0 = pos1 65 | pos1 = centers 66 | pairs, distances = particles.get_links_size(pos0[:,:2], pos0[:,2], pos1[:,:2], pos1[:,2], maxdist=2) 67 | linker.addFrame(len(pos1), pairs, distances) 68 | #output 69 | np.savetxt( 70 | splitext(pattern%t)[0]+'.csv', 71 | np.column_stack((linker.pos2tr[-1], centers)), 72 | fmt='%g' 73 | ) 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /python/colloids/traj2h5.py: -------------------------------------------------------------------------------- 1 | import sys, os.path, argparse, shutil 2 | import numpy as np 3 | from pandas import DataFrame 4 | import trackpy as tp 5 | from colloids import experiment as xp 6 | from colloids.progressbar import ProgressBar 7 | 8 | if __name__ == '__main__': 9 | parser = argparse.ArgumentParser(description='Convert coordinates and trajectory data to a HDF5 format compatible with trackpy.PandasHDFStoreSingleNode.') 10 | parser.add_argument('trname', help='Trajectory file name') 11 | parser.add_argument('--out', help='The file.h5 where to save the data. By default the same name as trajectory file, one level below in the directory tree.') 12 | args = parser.parse_args() 13 | trname = args.trname 14 | print(trname) 15 | x = xp.Experiment(trname) 16 | 17 | if args.out is None: 18 | args.out = os.path.join( 19 | os.path.split(x.path)[0], 20 | os.path.splitext(x.trajfile)[0]+'.h5' 21 | ) 22 | print('to %s'%args.out) 23 | assert x.size < 2**15, "Too many time steps, use larger data types" 24 | assert x.nb_trajs < 2**31, "Too many trajectories, use larger data types" 25 | 26 | pro = ProgressBar(x.size) 27 | with tp.PandasHDFStoreSingleNode(args.out) as s: 28 | for t, name in x.enum(): 29 | pro.animate(t) 30 | d = {x:c for x,c in zip( 31 | 'xyz', 32 | np.loadtxt(name, skiprows=2, unpack=True, dtype=np.float16) 33 | )} 34 | d['frame'] = np.full(d['x'].shape, t, dtype=np.int16) 35 | d['particle'] = x.p2tr(t).astype(np.int32) 36 | s.put(DataFrame(d)) 37 | pro.animate(x.size) 38 | -------------------------------------------------------------------------------- /test/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define BOOST_TEST_MODULE tracker test 3 | #define BOOST_TEST_DYN_LINK 4 | 5 | #include 6 | #include "../graphic/tracker.hpp" 7 | 8 | using namespace Colloids; 9 | 10 | /*void images_are_close(const cv::Mat &a, const cv::Mat &b, float precision) 11 | { 12 | OctaveFinder::Image M = cv::abs(a)+cv::abs(b); 13 | double peak = *std::max_element(M.begin(), M.end()); 14 | BOOST_REQUIRE_CLOSE(cv::sum(a)[0], cv::sum(b)[0], precision/peak); 15 | cv::Mat_ diff = cv::abs(a-b) / peak; 16 | cv::MatConstIterator_ u = diff.begin(); 17 | for(int i=0; i "< 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace Colloids; 11 | using namespace boost::posix_time; 12 | 13 | BOOST_AUTO_TEST_SUITE( serieTracker ) 14 | 15 | BOOST_AUTO_TEST_SUITE( serieTrackerConstructor ) 16 | 17 | BOOST_AUTO_TEST_CASE( single_image ) 18 | { 19 | boost::array xyzt = {{16, 16, 1, 1}}; 20 | std::string inputFile = "test_input/single_image.tif"; 21 | SerieTracker track(inputFile, xyzt, 1.0, 0, FFTW_ESTIMATE); 22 | BOOST_CHECK_EQUAL(track.getPattern(), inputFile); 23 | BOOST_CHECK(!track.has_depth()); 24 | BOOST_CHECK(!track.has_time()); 25 | xyzt[2] = 2; 26 | BOOST_CHECK_THROW(SerieTracker track2(inputFile, xyzt, 1.0, 0, FFTW_ESTIMATE), std::invalid_argument); 27 | xyzt[2] = 1; 28 | xyzt[3] = 2; 29 | BOOST_CHECK_THROW(SerieTracker track2(inputFile, xyzt, 1.0, 0, FFTW_ESTIMATE), std::invalid_argument); 30 | } 31 | 32 | BOOST_AUTO_TEST_CASE( zSeries ) 33 | { 34 | boost::array xyzt = {{16, 16, 16, 1}}; 35 | std::string inputFile = "test_input/ZSerie_z00.tif"; 36 | SerieTracker track(inputFile, xyzt, 1.0, 0, FFTW_ESTIMATE); 37 | BOOST_CHECK(track.has_depth()); 38 | BOOST_CHECK(!track.has_time()); 39 | BOOST_CHECK_EQUAL(track.getPattern(), "test_input/ZSerie_z%|02d|.tif"); 40 | } 41 | BOOST_AUTO_TEST_CASE( tSeries ) 42 | { 43 | boost::array xyzt = {{16, 16, 1, 3}}; 44 | std::string inputFile = "test_input/TSerie_t000.tif"; 45 | SerieTracker track(inputFile, xyzt, 1.0, 0, FFTW_ESTIMATE); 46 | BOOST_CHECK(!track.has_depth()); 47 | BOOST_CHECK(track.has_time()); 48 | BOOST_CHECK_EQUAL(track.getPattern(), "test_input/TSerie_t%|03d|.tif"); 49 | } 50 | BOOST_AUTO_TEST_CASE( ztSeries ) 51 | { 52 | boost::array xyzt = {{16, 16, 1, 3}}; 53 | std::string inputFile = "test_input/ZTSerie_z00_t000.tif"; 54 | SerieTracker track(inputFile, xyzt, 1.0, 0, FFTW_ESTIMATE); 55 | BOOST_CHECK(track.has_depth()); 56 | BOOST_CHECK(track.has_time()); 57 | BOOST_CHECK_EQUAL(track.getPattern(), "test_input/ZTSerie_z%|02d|_t%|03d|.tif"); 58 | } 59 | 60 | BOOST_AUTO_TEST_SUITE_END() //serieTrackerConstructor 61 | 62 | BOOST_AUTO_TEST_SUITE_END() //serieTracker 63 | -------------------------------------------------------------------------------- /test_input/TSerie_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/TSerie_t000.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z00.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z00.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z01.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z01.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z02.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z02.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z03.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z03.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z04.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z04.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z05.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z05.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z06.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z06.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z07.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z07.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z08.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z08.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z09.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z09.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z10.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z10.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z11.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z11.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z12.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z12.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z13.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z13.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z14.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z14.tif -------------------------------------------------------------------------------- /test_input/ZSerie_z15.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZSerie_z15.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z00_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z00_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z01_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z01_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z02_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z02_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z03_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z03_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z04_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z04_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z05_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z05_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z06_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z06_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z07_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z07_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z08_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z08_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z09_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z09_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z10_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z10_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z11_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z11_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z12_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z12_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z13_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z13_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z14_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z14_t000.tif -------------------------------------------------------------------------------- /test_input/ZTSerie_z15_t000.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/ZTSerie_z15_t000.tif -------------------------------------------------------------------------------- /test_input/single_image.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuLeocmach/colloids/1387ce920d05b57ed28ed5fa4d1337164dd03014/test_input/single_image.tif -------------------------------------------------------------------------------- /tracker.cbp.linux: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 72 | 73 | --------------------------------------------------------------------------------