$treeview $search $mathjax
Palabos  Version 1.1
$projectbrief
$projectbrief
$searchbox

imageWriter.hh

Go to the documentation of this file.
00001 /* This file is part of the Palabos library.
00002  *
00003  * Copyright (C) 2011 FlowKit Sarl
00004  * Avenue de Chailly 23
00005  * 1012 Lausanne, Switzerland
00006  * E-mail contact: contact@flowkit.com
00007  *
00008  * The most recent release of Palabos can be downloaded at 
00009  * <http://www.palabos.org/>
00010  *
00011  * The library Palabos is free software: you can redistribute it and/or
00012  * modify it under the terms of the GNU Affero General Public License as
00013  * published by the Free Software Foundation, either version 3 of the
00014  * License, or (at your option) any later version.
00015  *
00016  * The library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Affero General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Affero General Public License
00022  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00023 */
00024 
00025 #ifndef IMAGE_WRITER_HH
00026 #define IMAGE_WRITER_HH
00027 
00028 #include "parallelism/mpiManager.h"
00029 #include "core/globalDefs.h"
00030 #include "core/plbProfiler.h"
00031 #include "io/imageWriter.h"
00032 #include "io/colormaps.h"
00033 #include "atomicBlock/dataField2D.h"
00034 #include "atomicBlock/dataField3D.h"
00035 #include "core/runTimeDiagnostics.h"
00036 #include "dataProcessors/dataAnalysisWrapper2D.h"
00037 #include <fstream>
00038 #include <cstdlib>
00039 #include <cmath>
00040 #include <sstream>
00041 #include <string>
00042 #include <vector>
00043 
00044 namespace plb {
00045 
00047 
00048 template<typename T>
00049 ImageWriter<T>::ImageWriter(std::string const& map)
00050     : colorRange(1024),
00051       numColors(1024),
00052       colorMap( mapGenerators::generateMap(map) )
00053 { }
00054 
00055 template<typename T>
00056 ImageWriter<T>::ImageWriter(std::string const& map, plint colorRange_, plint numColors_)
00057     : colorRange(colorRange_),
00058       numColors(numColors_),
00059       colorMap( mapGenerators::generateMap(map) )
00060 { }
00061 
00062 template<typename T>
00063 void ImageWriter<T>::setMap(std::string const& map, plint colorRange_, plint numColors_) {
00064     colorRange = colorRange_;
00065     numColors  = numColors_;
00066     colorMap   = mapGenerators::generateMap(map);
00067 }
00068 
00069 template<typename T>
00070 void ImageWriter<T>::writePpm (
00071         std::string const& fName,
00072         ScalarField2D<T>& field,
00073         T minVal, T maxVal) const
00074 {
00075     writePpmImplementation(fName, field, minVal, maxVal);
00076 }
00077 
00078 template<typename T>
00079 void ImageWriter<T>::writeGif(std::string const& fName,
00080                               ScalarField2D<T>& field,
00081                               T minVal, T maxVal) const
00082 {
00083     writePpm(fName, field, minVal, maxVal);
00084     imageMagickPpmToGif(fName);
00085 }
00086 
00087 template<typename T>
00088 void ImageWriter<T>::writeGif(std::string const& fName,
00089                               ScalarField2D<T>& field,
00090                               T minVal, T maxVal,
00091                               plint sizeX, plint sizeY) const
00092 {
00093     writePpm(fName, field, minVal, maxVal);
00094     imageMagickResize(fName, sizeX, sizeY);
00095 }
00096 
00097 template<typename T>
00098 void ImageWriter<T>::writeScaledGif(std::string const& fName,
00099                                     ScalarField2D<T>& field) const
00100 {
00101     writeGif(fName, field, T(), T());
00102 }
00103 
00104 template<typename T>
00105 void ImageWriter<T>::writeScaledGif(std::string const& fName,
00106                                     ScalarField2D<T>& field,
00107                                     plint sizeX, plint sizeY) const
00108 {
00109     writeGif(fName, field, T(), T(), sizeX, sizeY);
00110 }
00111 
00112 template<typename T>
00113 void ImageWriter<T>::writeScaledPpm(std::string const& fName,
00114                                     ScalarField2D<T>& field) const
00115 {
00116     writePpm(fName, field, T(), T());
00117 }
00118 
00119 
00120 template<typename T>
00121 void ImageWriter<T>::writePpm (
00122         std::string const& fName,
00123         MultiScalarField2D<T>& field,
00124         T minVal, T maxVal) const
00125 {
00126     global::profiler().start("io");
00127     ScalarField2D<T> localField(field.getNx(), field.getNy());
00128     copySerializedBlock(field, localField);
00129     writePpmImplementation(fName, localField, minVal, maxVal);
00130     global::profiler().stop("io");
00131 }
00132 
00133 template<typename T>
00134 void ImageWriter<T>::writeGif(std::string const& fName,
00135                               MultiScalarField2D<T>& field,
00136                               T minVal, T maxVal) const
00137 {
00138     writePpm(fName, field, minVal, maxVal);
00139     imageMagickPpmToGif(fName);
00140 }
00141 
00142 template<typename T>
00143 void ImageWriter<T>::writeGif(std::string const& fName,
00144                               MultiScalarField2D<T>& field,
00145                               T minVal, T maxVal,
00146                               plint sizeX, plint sizeY) const
00147 {
00148     writePpm(fName, field, minVal, maxVal);
00149     imageMagickResize(fName, sizeX, sizeY);
00150 }
00151 
00152 template<typename T>
00153 void ImageWriter<T>::writeScaledGif(std::string const& fName,
00154                                     MultiScalarField2D<T>& field) const
00155 {
00156     writeGif(fName, field, T(), T());
00157 }
00158 
00159 template<typename T>
00160 void ImageWriter<T>::writeScaledGif(std::string const& fName,
00161                                     MultiScalarField2D<T>& field,
00162                                     plint sizeX, plint sizeY) const
00163 {
00164     writeGif(fName, field, T(), T(), sizeX, sizeY);
00165 }
00166 
00167 template<typename T>
00168 void ImageWriter<T>::writeScaledPpm(std::string const& fName,
00169                                     MultiScalarField2D<T>& field) const
00170 {
00171     writePpm(fName, field, T(), T());
00172 }
00173 
00174 
00175 template<typename T>
00176 void ImageWriter<T>::writePpm (
00177         std::string const& fName,
00178         ScalarField3D<T>& field,
00179         T minVal, T maxVal) const
00180 {
00181     plint nx=0, ny=0;
00182     if (field.getNx()==1) {
00183         nx = field.getNy();
00184         ny = field.getNz();
00185     }
00186     else if (field.getNy()==1) {
00187         nx = field.getNx();
00188         ny = field.getNz();
00189     }
00190     else if (field.getNz()==1) {
00191         nx = field.getNx();
00192         ny = field.getNy();
00193     }
00194     else {
00195         return;
00196     }
00197 
00198     ScalarField2D<T> localField(nx,ny);
00199     serializerToUnSerializer(
00200             field.getBlockSerializer(field.getBoundingBox(), IndexOrdering::forward),
00201             localField.getBlockUnSerializer(localField.getBoundingBox(), IndexOrdering::forward) );
00202     writePpmImplementation(fName, localField, minVal, maxVal);
00203 }
00204 
00205 template<typename T>
00206 void ImageWriter<T>::writeGif(std::string const& fName,
00207                               ScalarField3D<T>& field,
00208                               T minVal, T maxVal) const
00209 {
00210     writePpm(fName, field, minVal, maxVal);
00211     imageMagickPpmToGif(fName);
00212 }
00213 
00214 template<typename T>
00215 void ImageWriter<T>::writeGif(std::string const& fName,
00216                               ScalarField3D<T>& field,
00217                               T minVal, T maxVal,
00218                               plint sizeX, plint sizeY) const
00219 {
00220     writePpm(fName, field, minVal, maxVal);
00221     imageMagickResize(fName, sizeX, sizeY);
00222 }
00223 
00224 template<typename T>
00225 void ImageWriter<T>::writeScaledGif(std::string const& fName,
00226                                     ScalarField3D<T>& field) const
00227 {
00228     writeGif(fName, field, T(), T());
00229 }
00230 
00231 template<typename T>
00232 void ImageWriter<T>::writeScaledGif(std::string const& fName,
00233                                     ScalarField3D<T>& field,
00234                                     plint sizeX, plint sizeY) const
00235 {
00236     writeGif(fName, field, T(), T(), sizeX, sizeY);
00237 }
00238 
00239 template<typename T>
00240 void ImageWriter<T>::writeScaledPpm(std::string const& fName,
00241                                     ScalarField3D<T>& field) const
00242 {
00243     writePpm(fName, field, T(), T());
00244 }
00245 
00246 
00247 
00248 template<typename T>
00249 void ImageWriter<T>::writePpm (
00250         std::string const& fName,
00251         MultiScalarField3D<T>& field,
00252         T minVal, T maxVal) const
00253 {
00254     plint nx=0, ny=0;
00255     if (field.getNx()==1) {
00256         nx = field.getNy();
00257         ny = field.getNz();
00258     }
00259     else if (field.getNy()==1) {
00260         nx = field.getNx();
00261         ny = field.getNz();
00262     }
00263     else if (field.getNz()==1) {
00264         nx = field.getNx();
00265         ny = field.getNy();
00266     }
00267     else {
00268         return;
00269     }
00270 
00271     ScalarField2D<T> localField(nx,ny);
00272     serializerToUnSerializer(
00273             field.getBlockSerializer(field.getBoundingBox(), IndexOrdering::forward),
00274             localField.getBlockUnSerializer(localField.getBoundingBox(), IndexOrdering::forward) );
00275     writePpmImplementation(fName, localField, minVal, maxVal);
00276 }
00277 
00278 template<typename T>
00279 void ImageWriter<T>::writeGif(std::string const& fName,
00280                               MultiScalarField3D<T>& field,
00281                               T minVal, T maxVal) const
00282 {
00283     writePpm(fName, field, minVal, maxVal);
00284     imageMagickPpmToGif(fName);
00285 }
00286 
00287 template<typename T>
00288 void ImageWriter<T>::writeGif(std::string const& fName,
00289                               MultiScalarField3D<T>& field,
00290                               T minVal, T maxVal,
00291                               plint sizeX, plint sizeY) const
00292 {
00293     writePpm(fName, field, minVal, maxVal);
00294     imageMagickResize(fName, sizeX, sizeY);
00295 }
00296 
00297 template<typename T>
00298 void ImageWriter<T>::writeScaledGif(std::string const& fName,
00299                                     MultiScalarField3D<T>& field) const
00300 {
00301     writeGif(fName, field, T(), T());
00302 }
00303 
00304 template<typename T>
00305 void ImageWriter<T>::writeScaledGif(std::string const& fName,
00306                                     MultiScalarField3D<T>& field,
00307                                     plint sizeX, plint sizeY) const
00308 {
00309     writeGif(fName, field, T(), T(), sizeX, sizeY);
00310 }
00311 
00312 template<typename T>
00313 void ImageWriter<T>::writeScaledPpm(std::string const& fName,
00314                                     MultiScalarField3D<T>& field) const
00315 {
00316     writePpm(fName, field, T(), T());
00317 }
00318 
00319 template<typename T>
00320 bool equals(T a, T b) {
00321     return a==b;
00322 }
00323 
00324 template<> bool equals(float a, float b) {
00325     return std::fabs(a-b)<1.e-12;
00326 }
00327 
00328 template<> bool equals(double a, double b) {
00329     return std::fabs(a-b)<1.e-12;
00330 }
00331 
00332 template<typename T>
00333 void ImageWriter<T>::writePpmImplementation (
00334         std::string const& fName,
00335         ScalarField2D<T>& localField,
00336         T minVal, T maxVal) const
00337 {
00338     if (global::mpi().isMainProcessor()) {
00339         if (equals(minVal,maxVal)) {
00340             minVal = computeMin(localField);
00341             maxVal = computeMax(localField);
00342         }
00343         std::string fullName = global::directories().getImageOutDir() + fName+".ppm";
00344         std::ofstream fout(fullName.c_str());
00345         fout << "P3\n";
00346         fout << localField.getNx() << " " << localField.getNy() << "\n";
00347         fout << (colorRange-1) << "\n";
00348 
00349         for (plint iY=localField.getNy()-1; iY>=0; --iY) {
00350             for (plint iX=0; iX<localField.getNx(); ++iX) {
00351                 double outputValue = 0.;
00352                 if (! (minVal==maxVal) ) {
00353                     outputValue = ( (double) (localField.get(iX,iY)-minVal) /
00354                                     (double) (maxVal-minVal) *
00355                                     (double) (numColors-1) / (double) numColors );
00356                 }
00357                 if (outputValue <   0.) outputValue = 0.;
00358                 if (outputValue >=  1.) outputValue = (double) (numColors-1) / (double) numColors;
00359                 rgb color = colorMap.get(outputValue);
00360                 fout << (int) (color.r*(colorRange-1)) << " "
00361                      << (int) (color.g*(colorRange-1)) << " "
00362                      << (int) (color.b*(colorRange-1)) << "\n";
00363             }
00364         }
00365     }
00366 }
00367 
00368 template<typename T>
00369 void ImageWriter<T>::imageMagickPpmToGif(std::string const& fName) const {
00370     if (global::mpi().isMainProcessor()) {
00371 #ifdef PLB_USE_POSIX
00372         std::string convCommand =
00373             std::string("convert ") +
00374             global::directories().getImageOutDir() + fName + ".ppm " +
00375             global::directories().getImageOutDir() + fName + ".gif ";
00376             
00377         std::string rmCommand =
00378             std::string("/bin/rm ") +
00379             global::directories().getImageOutDir() + fName + ".ppm";
00380 
00381         plint errorConv = system(convCommand.c_str());
00382         if (errorConv != 0) plbWarning("Error in using ImageMagick convert command.");
00383         plint errorRm = system(rmCommand.c_str());
00384         if (errorRm != 0) plbWarning("Error in removing temporary ppm file.");
00385 #endif  // PLB_USE_POSIX
00386     }
00387 }
00388 
00389 template<typename T>
00390 void ImageWriter<T>::imageMagickResize( std::string const& fName,
00391                                         plint sizeX, plint sizeY) const
00392 {
00393     global::profiler().start("io");
00394 #ifdef PLB_USE_POSIX
00395     if (global::mpi().isMainProcessor()) {
00396         std::stringstream imStream;
00397         imStream << "convert -resize "
00398                  << sizeX << "x" << sizeY << " "
00399                  << global::directories().getImageOutDir()
00400                  << fName << ".ppm "
00401                  << global::directories().getImageOutDir()
00402                  << fName << ".gif";
00403         plint errorConv = system(imStream.str().c_str());
00404         if (errorConv != 0) plbWarning("Error in using ImageMagick convert command.");
00405 
00406         std::string rmCommand =
00407             std::string("/bin/rm ") +
00408             global::directories().getImageOutDir() + fName + ".ppm";
00409         plint errorRm = system(rmCommand.c_str());
00410         if (errorRm != 0) plbWarning("Error in removing temporary ppm file.");
00411     }
00412 #endif  // PLB_USE_POSIX
00413     global::profiler().stop("io");
00414 }
00415 
00416 }  // namespace plb
00417 
00418 #endif