Import Geant4 10.4.0 source tree
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Generated on : 24/9/2010
|
||||
#
|
||||
# $Id: CMakeLists.txt 99561 2016-09-27 07:04:12Z gcosmo $
|
||||
# $Id: CMakeLists.txt 105747 2017-08-16 13:16:13Z gcosmo $
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@@ -17,6 +17,10 @@ if (GEANT4_USE_FREETYPE)
|
||||
add_definitions(-DTOOLS_USE_EXPAT)
|
||||
endif()
|
||||
|
||||
if (GEANT4_USE_HDF5)
|
||||
add_definitions(-DTOOLS_USE_HDF5)
|
||||
endif()
|
||||
|
||||
add_subdirectory(accumulables)
|
||||
add_subdirectory(csv)
|
||||
add_subdirectory(g4tools)
|
||||
@@ -24,19 +28,36 @@ add_subdirectory(hntools)
|
||||
add_subdirectory(management)
|
||||
add_subdirectory(root)
|
||||
add_subdirectory(xml)
|
||||
if (GEANT4_USE_HDF5)
|
||||
add_subdirectory(hdf5)
|
||||
endif()
|
||||
|
||||
if(NOT GEANT4_BUILD_GRANULAR_LIBS)
|
||||
include(Geant4MacroLibraryTargets)
|
||||
GEANT4_GLOBAL_LIBRARY_TARGET(NAME G4analysis
|
||||
COMPONENTS
|
||||
accumulables/sources.cmake
|
||||
csv/sources.cmake
|
||||
g4tools/sources.cmake
|
||||
hntools/sources.cmake
|
||||
management/sources.cmake
|
||||
root/sources.cmake
|
||||
xml/sources.cmake
|
||||
)
|
||||
if (GEANT4_USE_HDF5)
|
||||
GEANT4_GLOBAL_LIBRARY_TARGET(NAME G4analysis
|
||||
COMPONENTS
|
||||
accumulables/sources.cmake
|
||||
csv/sources.cmake
|
||||
g4tools/sources.cmake
|
||||
hdf5/sources.cmake
|
||||
hntools/sources.cmake
|
||||
management/sources.cmake
|
||||
root/sources.cmake
|
||||
xml/sources.cmake
|
||||
)
|
||||
else()
|
||||
GEANT4_GLOBAL_LIBRARY_TARGET(NAME G4analysis
|
||||
COMPONENTS
|
||||
accumulables/sources.cmake
|
||||
csv/sources.cmake
|
||||
g4tools/sources.cmake
|
||||
hntools/sources.cmake
|
||||
management/sources.cmake
|
||||
root/sources.cmake
|
||||
xml/sources.cmake
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
+66
-1
@@ -1,4 +1,4 @@
|
||||
$Id: History 103532 2017-04-13 14:00:35Z gcosmo $
|
||||
$Id: History 107500 2017-11-17 11:06:53Z gcosmo $
|
||||
-------------------------------------------------------------------
|
||||
|
||||
=========================================================
|
||||
@@ -17,6 +17,71 @@ committal in the SVN repository !
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
|
||||
November 16, 2017 I. Hrivnacova (analysis-V10-03-17)
|
||||
- Updated to g4tools 4.2.1 (Guy Barrand):
|
||||
Coverity fixes.
|
||||
See History_tools for the complete list of modifications.
|
||||
|
||||
November 2, 2017 I. Hrivnacova (analysis-V10-03-16)
|
||||
- Fixed compilation warning
|
||||
|
||||
October 25, 2017 I. Hrivnacova (analysis-V10-03-15)
|
||||
- Updated to g4tools 4.2.0 (Guy Barrand):
|
||||
Changes in wroot, rroot in order to handle row wise ntuple in case of MT or MPI.
|
||||
See History_tools for the complete list of modifications.
|
||||
- Added rowWise option to G4RootAnalysisManager::SetNtupleMerging()
|
||||
|
||||
October 19, 2017 I. Hrivnacova (analysis-V10-03-14)
|
||||
- Fixed compiler warning in G4Hdf5FileManager.cc
|
||||
|
||||
September 26, 2017 I. Hrivnacova (analysis-V10-03-13)
|
||||
- Updated to g4tools 3.7.0 (Guy Barrand):
|
||||
- Update in colorf, colors to make possible to use the tools/colors color
|
||||
table in G4Colour class.
|
||||
- Coverity fixes graphics/plotting code.
|
||||
See History_tools for the complete list of modifications.
|
||||
|
||||
September 11, 2017 I. Hrivnacova (analysis-V10-03-12)
|
||||
- Fixed generating file name on workers (adding _tN extension).
|
||||
(The problem was reported in analysis category in hypernews as item #537.)
|
||||
|
||||
August 3, 2017 I. Hrivnacova (analysis-V10-03-11)
|
||||
- Updated to g4tools 3.6.0 (Guy Barrand):
|
||||
Fixing problems introduced in previous version.
|
||||
See History_tools for the complete list of modifications.
|
||||
|
||||
August 1, 2017 I. Hrivnacova (analysis-V10-03-09, 10)
|
||||
- Several fixes in hdf5
|
||||
- Updated to g4tools 3.5.0 (Guy Barrand):
|
||||
Coverity fixes and test/cpp/hdf5_threads.cpp program.
|
||||
See History_tools for the complete list of modifications.
|
||||
|
||||
July 27, 2017 I. Hrivnacova (analysis-V10-03-08)
|
||||
- Adding support for Hdf5
|
||||
- Updated to g4tools 3.4.0 (Guy Barrand):
|
||||
See History_tools for the complete list of modifications.
|
||||
|
||||
July 21, 2017 I. Hrivnacova (analysis-V10-03-07)
|
||||
- Updated to g4tools 3.3.0 (Guy Barrand):
|
||||
Adding support for HDF5, improved tests.
|
||||
See History_tools for the complete list of modifications.
|
||||
|
||||
July 21, 2017 I. Hrivnacova (analysis-V10-03-06)
|
||||
- Fixing remaining compilation warnings (gcc)
|
||||
|
||||
July 21, 2017 I. Hrivnacova (analysis-V10-03-05)
|
||||
- Fixing compilation warnings (gcc53)
|
||||
|
||||
July 20, 2017 I. Hrivnacova (analysis-V10-03-04)
|
||||
- Code improvements:
|
||||
- Moved common implementation from G4V[R]NtupleManager in
|
||||
new G4Base[R]NtupleManager classes
|
||||
- Introduced G4TRNtupleDescription, G4TRNtupleManager template classes
|
||||
- Always create an ntuple from ntuple booking (removed usage of
|
||||
ntupel::create_column)
|
||||
- Added an optional directoryName argument in Read[Hn][Pn][Ntuple]
|
||||
functions in G4VAnalysisReader (needed for HDF5)
|
||||
|
||||
April 12, 2017 I. Hrivnacova (analysis-V10-03-03)
|
||||
- Corrected handling of open file failure
|
||||
(This fixes problem report #1957.)
|
||||
|
||||
@@ -1,3 +1,205 @@
|
||||
4.2.1 : fix Coverity notifications.
|
||||
- wroot/MT_SET_MAX.icc : protect usage of null object in "return false" messages.
|
||||
- wroot/ntuple : tree : create_branch : add a null pointer check.
|
||||
- wroot/tree : create_column_vector : displace col null pointer up one line.
|
||||
- wroot/base_leaf : (protected) cp cstor : add some missing fields initialisation.
|
||||
- rroot/base_leaf : (protected) cp cstor : add some missing fields initialisation.
|
||||
|
||||
4.2.0 : correction to pass integration in Geant4 (for the 10.4) :
|
||||
- aida_ntuple : id_class() method.
|
||||
- ntuple_binding : add_column_cid() method.
|
||||
- wroot/branch : fill(), add_basket() : have a check "m_write_basket>=m_max_baskets".
|
||||
- wroot/mt_ntuple_column_wise : in add_row() and end_fill() : check m_cols.size() versus m_main_branches.size().
|
||||
|
||||
4.1.0 : wroot : have material/corrections in order to do ntuple booking without the "ref" logic for all column types.
|
||||
- test/cpp/mt_ntuple.cpp : now an example with the "variable on column" logic for all column types.
|
||||
- test/cpp/mt_ntuple_ref.cpp : example with the "user variable ref" logic for all column types.
|
||||
|
||||
4.0.0 : changes in wroot, rroot in order to handle row wise ntuple in case of multi-thread or MPI.
|
||||
- wroot : branch::end_pfill : do not add empty basket.
|
||||
- wroot : ObjArray => obj_array, List => obj_list.
|
||||
- wroot : Windows : get_me() to avoid usage of *this in constructor.
|
||||
- wroot : icol : get_branch() return ref and not a pointer.
|
||||
- wroot : leaf_ref, leaf_string_ref, leaf_std_vector_ref : _ref logic to have same logic than for other drivers.
|
||||
- wroot : leaf : rm m_title field : mimick ROOT logic.
|
||||
- wroot : base_leaf : handle m_leaf_count object.
|
||||
- wroot : columns.icc : to put column code in common between ntuple and base_pntuple.
|
||||
- wroot : new file to support row wise ntuple for MT and MPI : SET_MAX.icc, base_pntuple_column_wise, base_pntuple_row_wise
|
||||
basket_add, impi_ntuple, imt_ntuple,
|
||||
mpi_basket_add, mpi_create_basket, mpi_ntuple_column_wise, mpi_ntuple_row_wise, mpi_protocol.
|
||||
- wroot : pntuple => mt_ntuple_column_wise, mpi_pntuple => mpi_ntuple_column_wise.
|
||||
|
||||
- rroot : ntuple : handle row_wise.
|
||||
- rroot : base_leaf : handle m_is_range field, handle m_own_leaf_count.
|
||||
- rroot : leaf : handle leaf_count logic : it permits to store std::vector of basic type on a leaf<T>.
|
||||
- rroot : named splitted in iros, object, list, obj_array, named.
|
||||
- rroot : buffer : read_object() : handle a trailing bool& a_created argument. It helps to know if
|
||||
the created object is managed or not.
|
||||
- rroot : Windows : get_me() to avoid usage of *this in constructor.
|
||||
- rroot : ObjArray => obj_array, List => obj_list.
|
||||
|
||||
- ntuple_binding : handle class id in column_binding.
|
||||
- ntuple_booking : has_similar_layout() : to compare with another ntuple_booking object. Used in MT to be sure MT booking object
|
||||
as the same "layout" than the one coming from the main.
|
||||
|
||||
- wcsv_ntuple : in _ref columns, pass user variable as const.
|
||||
|
||||
- hdf5 : header : to write/read a "header" with general infos as the name of the writing library and the "data schema version.".
|
||||
|
||||
- test/cpp : pwroot.cpp => mt_ntuple.cpp, wroot_pntuple.cpp => mt_ntuple_seq.cpp.
|
||||
- test/cpp : read_root.icc : used in mt_ntuple.cpp, mpi_ntuple.cpp to check consistency.
|
||||
|
||||
- test/cpp : cern_root_read_rg_rbw.cpp : to check that the ntuple in .root files produced by mt_ntuple.cpp
|
||||
and mpi_ntuple.cpp are readable by CERN-ROOT.
|
||||
|
||||
3.7.0 : quiet some Coverity notifications. In default code, remove some "a_inc" logic in some classes.
|
||||
It comes from a revisit to the way we can decount static object deletion (by using an atexit logic in apps).
|
||||
- tools/mem : have most methods protected. In the static list(), have the s_list on the heap.
|
||||
It permits to have an atexit logic in apps that permits to count the deletion of static objects.
|
||||
- tools/cstr, putenv : #ifdef TOOLS_MEM the "a_inc" argument in str_dup. In put_env(), do not use this
|
||||
argument in default code.
|
||||
- tools/colorf, colors : #ifdef TOOLS_MEM the a_inc argument in constructor. In colors, have a coworking
|
||||
cpp TOOLS_MEM_ATEXIT logic so that this argument is not used in default code.
|
||||
- tools/lina/mat, mat4, vec3, vec4, vec4f : #ifdef TOOLS_MEM the a_inc argument in constructor.
|
||||
In sg/base_camera, have a coworking cpp TOOLS_MEM_ATEXIT logic so that this argument is not used in
|
||||
default code of id_orientation().
|
||||
- test/cpp/viewplot.cpp : #ifdef TOOLS_MEM : example of an atexit final object counting.
|
||||
- tools/glutess/normal : static_ComputeNormal : remove Coverity warnings about not initialized minVert,
|
||||
maxVert variables.
|
||||
|
||||
3.6.0 :
|
||||
- mesh : Coverity 96394 : in __gl_meshDelete : return to the original code which is in fact ok! Coverity
|
||||
had been adused by (too much) clever C code.
|
||||
- sweep : Coverity 96379 : have "#ifndef NDEBUG" around fixedEdges++.
|
||||
- test/cpp/build : have : cppflags -DNDEBUG.
|
||||
- test/cpp/build : rm test/hdf5_threads.cpp for utest.
|
||||
- test/cpp/build : have use_dl for utest if using hdf5.
|
||||
|
||||
3.5.0 : Coverity fixes and test/cpp/hdf5_threads.cpp program.
|
||||
- hatcher.icc : 96393. Rm dead code.
|
||||
- bsf : 96392 : bsf() : initialize m_value.
|
||||
- hatcher.icc : 96393 : have a : delete [] listPoints;
|
||||
- plotter : 96389 : comment out some not used variables.
|
||||
- legend : 96388 : comment out some "rep_line" dead code.
|
||||
- plots : 96387, 96386 : fix an unneeded "if".
|
||||
- data_axis : 96385 : avoid a not needed test.
|
||||
- valop : 96380 : correct func_1() return logic.
|
||||
- sweep : 96379 : have assert(++fixedEdges==1) in two steps.
|
||||
- mesh : 96394 : in __gl_meshDelete : fix a eDel->Lface bad access.
|
||||
- test/cpp/hdf5_threads.cpp : to test HDF5 and threads. It needs a HDF5 lib built with "configure --enable-threadsafe".
|
||||
|
||||
3.3.0 : hdf5 : arrange to compile without -DH5_USE_16_API (then use 1.18 API if using hdf5/1.18.x).
|
||||
- tools/hdf5 : hdf5_h : tools_H5<xxx> : in order to compile hdf5 related code with 1.18 API.
|
||||
- tools/hdf5 : * : use tools_H5<xxx>.
|
||||
- tools/h2file : use not_a_profile() in write/read_histo(). It permits to enforce that profiles must be used with
|
||||
write/read_profile() functions.
|
||||
- tools/ntuple : constructor for writing : supress the "bool write" argument. "bool compress, uint basket_size" args
|
||||
permit to sign a constructor for writing.
|
||||
- tools/ntuple : constructor for reading : suppress the "bool a_write,bool compress, uint basket_size" arguments that
|
||||
are not needed when reading.
|
||||
- tools/ntuple : constructor for reading : have a constructor with a tools::ntuple_binding argument.
|
||||
- tools/ntuple : have column_ref, std_vector_column_ref, column_ref classes. It permits to handle properly the binding
|
||||
of a user variable at write, but also at read.
|
||||
- test/cpp/use_hdf5 : comment out usage of -DH5_USE_16_API.
|
||||
- test/cpp/hdf5_ntuple.cpp : revisit ntuple constructors for writing and reading as described upper.
|
||||
- test/cpp/hdf5_ntuple.cpp : have an example of reading by using tools::ntuple_binding.
|
||||
- tools/wcsv_histo : tools::wcsv::hto : use not_a_profile(). Now this template will not compile if passing a profile. (For
|
||||
a profile someone has to use the tools::wcsv::pto template).
|
||||
- tools/histo/h1,h2,h3 : dummy not_a_profile() method to write templated function dedicated to histo but not intended
|
||||
for profile.
|
||||
- tools/utest : handle -no_<name> argument.
|
||||
- tools/lina/geom3 : some unsigned int => size_t.
|
||||
- tools/system : rmenv() => rm_env().
|
||||
|
||||
3.2.0 : test/cpp/utest.cpp to do unitary tests.
|
||||
- test/cpp/utest : have test/viewplot_ttf.cpp test. It permits to test plotting with freetype.
|
||||
- test/cpp/utest : have test/lego_offscreen.cpp test. It permits to test 3D plotting with freetype.
|
||||
- WARNING : freetype related tests may not pass according the version of freetype. They do not pass with a :
|
||||
* 2.7.0 on my Mac
|
||||
* 2.5.5 on another Mac (macpro4).
|
||||
whilst it is ok with a :
|
||||
* 2.8.0 on my Mac
|
||||
* 2.5.2 on ubuntu
|
||||
* the 2.1.9 of softinex/ourex/freetype on Windows-10/64, ubuntu, macOS.
|
||||
|
||||
- to build and execute freetype related tests :
|
||||
UNIX> ./build -expat -freetype utest.cpp
|
||||
UNIX> ./tools_test_utest
|
||||
(UNIX> ./tools_test_utest -verbose)
|
||||
To build and execute hdf5 related tests :
|
||||
UNIX> ./build -hdf5 utest.cpp
|
||||
UNIX> ./tools_test_utest
|
||||
To have the list of compiled tests :
|
||||
UNIX> ./tools_test_utest -list
|
||||
|
||||
3.1.0 :
|
||||
- test/cpp/cern_root_hdf5_ntuple.cpp : program to read the ntuple.hdf5 file produced with hdf5_ntuple.cpp and to
|
||||
plot a column projection by using CERN-ROOT/TH and TCanvas.
|
||||
- test/cpp/use_cern_root, setup_cern_root.sh, setup_cern_root.csh : to access CERN-ROOT to compile, link and run
|
||||
the cern_root_hdf5_ntuple.cpp program.
|
||||
- test/cpp/use_zip, use_thread : to put in common acces to zlib, thread for the various programs that use them.
|
||||
- test/sys/process, dir : for unitary test program.
|
||||
- test/cpp/utest.cpp, test/*.cpp : unitary test program.
|
||||
|
||||
3.0.0 : hdf5 write/read. contour plotting. w/r-root : handle branch_objet.
|
||||
Various modifs coming from inlib/exlib dev done for other applications :
|
||||
- tools/hdf : material to write/read histos and ntuple at the HDF5 file format.
|
||||
- test/cpp/hdf5_histos.cpp : example to write/read histos with HDF5.
|
||||
- test/cpp/hdf5_ntuple.cpp : example to write/read an ntuple with HDF5.
|
||||
|
||||
- tools/ccontour, clist_contour, hatcher, hatcher.icc, tess_contour, valop : for plotting contours.
|
||||
- tools/sg/plotter : code to have contour plotting.
|
||||
- tools/spline : to have nice function plotting.
|
||||
|
||||
- tools/rroot/branch_object, iobject, cids, fac, leaf : handle branch_object.
|
||||
- tools/rroot/tree_manip : find_leaf, find_branch_element, read_leaf, read_leaf_object, read_std_vec.
|
||||
- tools/rroot/branch, branch_element, file, tree : number of entries : uint32 => uint64.
|
||||
- tools/rroot/ntuple : column_string::fetch_entry : test if m_leaf.value() is null.
|
||||
- tools/rroot/streamers/TH3D_stream : m_axes.resize(3), instead of 2.
|
||||
|
||||
- tools/wroot/branch_object, cids : handle branch_object.
|
||||
- tools/wroot/basket : in stream(), handle "displacement".
|
||||
- tools/wroot/branch : reset() method.
|
||||
- tools/wroot/branch, buffer : in fill() : buf.reset_objs_map().
|
||||
- tools/wroot/ntuple : column_ref : to handle user variable binding at write.
|
||||
- tools/wroot/tree : cstor : managed argument.
|
||||
- tools/wroot/tree : have a reset method.
|
||||
|
||||
- tools/rcsv_ntuple : handle int64, uint64, bool columns.
|
||||
- tools/wcsv_ntuple : column_ref to be able to bind a user variable on simple type columns.
|
||||
- test/cpp/rcsv.cpp => rcsv_ntuple.cpp
|
||||
- test/cpp/wcsv.cpp => wcsv_ntuple.cpp
|
||||
- test/cpp/wcsv_booking.cpp => wcsv_ntuple_booking.cpp
|
||||
- test/cpp/wcsv_booking_bind.cpp : to show user variable binding on simple type columns.
|
||||
|
||||
- tools/ntuple_booking, ntuple_binding : can pass now a user variable for simple types.
|
||||
|
||||
- tools/histo/axis, histo_data, base_histo, p1, p2, : equals method to be able to compare easily histos.
|
||||
- tools/histo/c1d,c2d,c3d : inline code in the classes.
|
||||
- tools/histo/h1,h2,h3 : get_bin_content method.
|
||||
- tools/histo/h1d,h2d,h3d,p1d,p2d,h2df,h3df : have a default constructor building a valid histo : needed when reading from file.
|
||||
|
||||
- tools/vmanip, sg/group, rroot/directory, named, waxml/ntuple : clear => safe_clear.
|
||||
- tools/sg/vertices, text_hershey, style_parser, style_colormap, primitive_visitor, render_action,
|
||||
manager_zb, normal, matrix, nodekit, line_set, head_light, pick_action, gl_manager, cube, h2plot,
|
||||
draw_style, node : rm some not needed "tools::".
|
||||
- tools/sg/set_plotter_camera : have a func to pass float x,y,z camera position.
|
||||
- tools/sg/text_style : options field.
|
||||
- tools/sg/strings : font_ROOT_<>() golabl strings.
|
||||
- tools/sg/plottable, plottables : bins1D, bins2D, func1D, func2D, points2D, points3D now in plottables.
|
||||
- tools/sg/viewer : fields m_produce_out_jpg, m_produce_out_png, m_produce_out_file.
|
||||
- tools/sg/legend, markers mnmx text_valop valop2sg : handle markers and text with upper/lower script in legend box.
|
||||
- tools/sg/atb_vertices : draw_edges field. Have code to draw edges for triangles.
|
||||
- tools/sg/bmf, mf : setup a multiple value field from one value or a std::vector of values.
|
||||
- tools/sg/plots : handle new fields left_margin, right_margin, top_margin, bottom_margin, horizontal_spacing, vertical_spacing.
|
||||
- tools/sg/axis : handle case of label at center of bin.
|
||||
|
||||
- tools/system : [is,get,put]env => [is,get,put]_env : to avoid clash with system functions.
|
||||
|
||||
2.4.0 :
|
||||
- test/cpp/mpi_ntuple.cpp : modifs to use an ntuple id.
|
||||
- tools/mpi/pntuple : handle a ntuple id.
|
||||
|
||||
2.3.0 :
|
||||
- test/cpp/mpi_ntuple.cpp : use a maximum tools::impi interface which does not bring mpi.h.
|
||||
- tools/mpi/pntuple : have the code using only the tools::impi interface.
|
||||
|
||||
@@ -68,17 +68,17 @@ class G4CsvAnalysisReader : public G4ToolsAnalysisReader
|
||||
protected:
|
||||
// virtual methods from base class
|
||||
virtual G4int ReadH1Impl(const G4String& h1Name, const G4String& fileName,
|
||||
G4bool isUserFileName) final;
|
||||
const G4String& dirName, G4bool isUserFileName) final;
|
||||
virtual G4int ReadH2Impl(const G4String& h2Name, const G4String& fileName,
|
||||
G4bool isUserFileName) final;
|
||||
const G4String& dirName, G4bool isUserFileName) final;
|
||||
virtual G4int ReadH3Impl(const G4String& h3Name, const G4String& fileName,
|
||||
G4bool isUserFileName) final;
|
||||
const G4String& dirName, G4bool isUserFileName) final;
|
||||
virtual G4int ReadP1Impl(const G4String& p1Name, const G4String& fileName,
|
||||
G4bool isUserFileName) final;
|
||||
const G4String& dirName, G4bool isUserFileName) final;
|
||||
virtual G4int ReadP2Impl(const G4String& p2Name, const G4String& fileName,
|
||||
G4bool isUserFileName) final;
|
||||
const G4String& dirName, G4bool isUserFileName) final;
|
||||
virtual G4int ReadNtupleImpl(const G4String& ntupleName, const G4String& fileName,
|
||||
G4bool isUserFileName) final;
|
||||
const G4String& dirName, G4bool isUserFileName) final;
|
||||
|
||||
private:
|
||||
// static data members
|
||||
|
||||
@@ -33,87 +33,24 @@
|
||||
#ifndef G4CsvRNtupleManager_h
|
||||
#define G4CsvRNtupleManager_h 1
|
||||
|
||||
#include "G4VRNtupleManager.hh"
|
||||
#include "G4TRNtupleManager.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
#include "tools/rcsv_ntuple"
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct G4CsvRNtupleDescription;
|
||||
|
||||
class G4CsvRNtupleManager : public G4VRNtupleManager
|
||||
class G4CsvRNtupleManager : public G4TRNtupleManager<tools::rcsv::ntuple>
|
||||
{
|
||||
friend class G4CsvAnalysisReader;
|
||||
|
||||
protected:
|
||||
explicit G4CsvRNtupleManager(const G4AnalysisManagerState& state);
|
||||
virtual ~G4CsvRNtupleManager();
|
||||
|
||||
// Methods to manipulate ntuples
|
||||
G4bool IsEmpty() const;
|
||||
G4bool Reset();
|
||||
|
||||
// Access methods
|
||||
tools::rcsv::ntuple* GetNtuple() const;
|
||||
tools::rcsv::ntuple* GetNtuple(G4int ntupleId) const;
|
||||
|
||||
// Functions independent from the output type
|
||||
//
|
||||
// Methods to read ntuple from a file
|
||||
G4int SetNtuple(G4CsvRNtupleDescription* rntupleDescription);
|
||||
// Methods for ntuple with id = FirstNtupleId
|
||||
virtual G4bool SetNtupleIColumn(const G4String& columnName,
|
||||
G4int& value);
|
||||
virtual G4bool SetNtupleFColumn(const G4String& columnName,
|
||||
G4float& value);
|
||||
virtual G4bool SetNtupleDColumn(const G4String& columnName,
|
||||
G4double& value);
|
||||
virtual G4bool SetNtupleSColumn(const G4String& columnName,
|
||||
G4String& value);
|
||||
// Bind the ntuple columns of vector type
|
||||
virtual G4bool SetNtupleIColumn(const G4String& columnName,
|
||||
std::vector<G4int>& vector);
|
||||
virtual G4bool SetNtupleFColumn(const G4String& columnName,
|
||||
std::vector<G4float>& vector);
|
||||
virtual G4bool SetNtupleDColumn(const G4String& columnName,
|
||||
std::vector<G4double>& vector);
|
||||
// Methods for ntuple with id > FirstNtupleId
|
||||
virtual G4bool SetNtupleIColumn(G4int ntupleId,
|
||||
const G4String& columnName, G4int& value);
|
||||
virtual G4bool SetNtupleFColumn(G4int ntupleId,
|
||||
const G4String& columnName, G4float& value);
|
||||
virtual G4bool SetNtupleDColumn(G4int ntupleId,
|
||||
const G4String& columnName, G4double& value);
|
||||
virtual G4bool SetNtupleSColumn(G4int ntupleId,
|
||||
const G4String& columnName, G4String& value);
|
||||
// Bind the ntuple columns of vector type
|
||||
virtual G4bool SetNtupleIColumn(G4int ntupleId, const G4String& columnName,
|
||||
std::vector<G4int>& vector);
|
||||
virtual G4bool SetNtupleFColumn(G4int ntupleId, const G4String& columnName,
|
||||
std::vector<G4float>& vector);
|
||||
virtual G4bool SetNtupleDColumn(G4int ntupleId, const G4String& columnName,
|
||||
std::vector<G4double>& vector);
|
||||
virtual G4bool GetNtupleRow();
|
||||
virtual G4bool GetNtupleRow(G4int ntupleId) ;
|
||||
|
||||
// Access methods
|
||||
virtual G4int GetNofNtuples() const;
|
||||
|
||||
private:
|
||||
// methods
|
||||
G4CsvRNtupleDescription* GetNtupleInFunction(G4int id,
|
||||
G4String function,
|
||||
G4bool warn = true) const;
|
||||
|
||||
// data members
|
||||
std::vector<G4CsvRNtupleDescription*> fNtupleVector;
|
||||
// Methods from the templated base class
|
||||
//
|
||||
virtual G4bool GetTNtupleRow(G4TRNtupleDescription<tools::rcsv::ntuple>* ntupleDescription) final;
|
||||
};
|
||||
|
||||
// inline functions
|
||||
|
||||
inline G4int G4CsvRNtupleManager::GetNofNtuples() const
|
||||
{ return fNtupleVector.size(); }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# Generated on : 15/07/2013
|
||||
#
|
||||
# $Id: sources.cmake 92688 2015-09-14 07:01:13Z gcosmo $
|
||||
# $Id: sources.cmake 105338 2017-07-21 09:14:27Z gcosmo $
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@@ -38,7 +38,6 @@ GEANT4_DEFINE_MODULE(NAME G4csv
|
||||
G4CsvFileManager.hh
|
||||
G4CsvNtupleManager.hh
|
||||
G4CsvRFileManager.hh
|
||||
G4CsvRNtupleDescription.hh
|
||||
G4CsvRNtupleManager.hh
|
||||
g4csv_defs.hh
|
||||
g4csv.hh
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "G4CsvAnalysisReader.hh"
|
||||
#include "G4CsvRFileManager.hh"
|
||||
#include "G4CsvRNtupleManager.hh"
|
||||
#include "G4CsvRNtupleDescription.hh"
|
||||
#include "G4AnalysisVerbose.hh"
|
||||
#include "G4AnalysisUtilities.hh"
|
||||
#include "G4Threading.hh"
|
||||
@@ -177,6 +176,7 @@ G4bool G4CsvAnalysisReader::Reset()
|
||||
//_____________________________________________________________________________
|
||||
G4int G4CsvAnalysisReader::ReadH1Impl(const G4String& h1Name,
|
||||
const G4String& fileName,
|
||||
const G4String& /*dirName*/,
|
||||
G4bool isUserFileName)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
@@ -218,6 +218,7 @@ G4int G4CsvAnalysisReader::ReadH1Impl(const G4String& h1Name,
|
||||
//_____________________________________________________________________________
|
||||
G4int G4CsvAnalysisReader::ReadH2Impl(const G4String& h2Name,
|
||||
const G4String& fileName,
|
||||
const G4String& /*dirName*/,
|
||||
G4bool isUserFileName)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
@@ -259,6 +260,7 @@ G4int G4CsvAnalysisReader::ReadH2Impl(const G4String& h2Name,
|
||||
//_____________________________________________________________________________
|
||||
G4int G4CsvAnalysisReader::ReadH3Impl(const G4String& h3Name,
|
||||
const G4String& fileName,
|
||||
const G4String& /*dirName*/,
|
||||
G4bool isUserFileName)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
@@ -300,6 +302,7 @@ G4int G4CsvAnalysisReader::ReadH3Impl(const G4String& h3Name,
|
||||
//_____________________________________________________________________________
|
||||
G4int G4CsvAnalysisReader::ReadP1Impl(const G4String& p1Name,
|
||||
const G4String& fileName,
|
||||
const G4String& /*dirName*/,
|
||||
G4bool isUserFileName)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
@@ -341,6 +344,7 @@ G4int G4CsvAnalysisReader::ReadP1Impl(const G4String& p1Name,
|
||||
//_____________________________________________________________________________
|
||||
G4int G4CsvAnalysisReader::ReadP2Impl(const G4String& p2Name,
|
||||
const G4String& fileName,
|
||||
const G4String& /*dirName*/,
|
||||
G4bool isUserFileName)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
@@ -383,6 +387,7 @@ G4int G4CsvAnalysisReader::ReadP2Impl(const G4String& p2Name,
|
||||
//_____________________________________________________________________________
|
||||
G4int G4CsvAnalysisReader::ReadNtupleImpl(const G4String& ntupleName,
|
||||
const G4String& fileName,
|
||||
const G4String& /*dirName*/,
|
||||
G4bool isUserFileName)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
@@ -404,7 +409,7 @@ G4int G4CsvAnalysisReader::ReadNtupleImpl(const G4String& ntupleName,
|
||||
|
||||
// Create ntuple
|
||||
auto rntuple = new tools::rcsv::ntuple(*ntupleFile);
|
||||
auto id = fNtupleManager->SetNtuple(new G4CsvRNtupleDescription(rntuple));
|
||||
auto id = fNtupleManager->SetNtuple(new G4TRNtupleDescription<tools::rcsv::ntuple>(rntuple));
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL2() )
|
||||
|
||||
@@ -28,393 +28,30 @@
|
||||
// Author: Ivana Hrivnacova, 25/07/2014 (ivana@ipno.in2p3.fr)
|
||||
|
||||
#include "G4CsvRNtupleManager.hh"
|
||||
#include "G4CsvRNtupleDescription.hh"
|
||||
#include "G4AnalysisManagerState.hh"
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4CsvRNtupleManager::G4CsvRNtupleManager(const G4AnalysisManagerState& state)
|
||||
: G4VRNtupleManager(state),
|
||||
fNtupleVector()
|
||||
{
|
||||
}
|
||||
: G4TRNtupleManager<tools::rcsv::ntuple>(state)
|
||||
{}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4CsvRNtupleManager::~G4CsvRNtupleManager()
|
||||
{
|
||||
std::vector<G4CsvRNtupleDescription*>::iterator it;
|
||||
for (it = fNtupleVector.begin(); it != fNtupleVector.end(); it++ ) {
|
||||
delete (*it);
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
//
|
||||
// private methods
|
||||
//
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4CsvRNtupleDescription* G4CsvRNtupleManager::GetNtupleInFunction(G4int id,
|
||||
G4String functionName, G4bool warn) const
|
||||
{
|
||||
G4int index = id - fFirstId;
|
||||
if ( index < 0 || index >= G4int(fNtupleVector.size()) ) {
|
||||
if ( warn) {
|
||||
G4String inFunction = "G4CsvRNtupleManager::";
|
||||
inFunction += functionName;
|
||||
G4ExceptionDescription description;
|
||||
description << " " << "ntuple " << id << " does not exist.";
|
||||
G4Exception(inFunction, "Analysis_WR011", JustWarning, description);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return fNtupleVector[index];
|
||||
}
|
||||
|
||||
//
|
||||
// protected methods
|
||||
//
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::IsEmpty() const
|
||||
G4bool G4CsvRNtupleManager::GetTNtupleRow(
|
||||
G4TRNtupleDescription<tools::rcsv::ntuple>* ntupleDescription)
|
||||
{
|
||||
return ! fNtupleVector.size();
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::Reset()
|
||||
{
|
||||
// Reset ntuples
|
||||
auto ntuple = ntupleDescription->fNtuple;
|
||||
|
||||
std::vector<G4CsvRNtupleDescription*>::iterator it;
|
||||
for (it = fNtupleVector.begin(); it != fNtupleVector.end(); it++ ) {
|
||||
// ntuple is deleted automatically when file is closed
|
||||
// delete (*it)->fNtuple;
|
||||
(*it)->fNtuple=0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
tools::rcsv::ntuple* G4CsvRNtupleManager::GetNtuple() const
|
||||
{
|
||||
return GetNtuple(fFirstId);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
tools::rcsv::ntuple* G4CsvRNtupleManager::GetNtuple(G4int ntupleId) const
|
||||
{
|
||||
G4CsvRNtupleDescription* rntupleDescription
|
||||
= GetNtupleInFunction(ntupleId, "GetNtuple");
|
||||
|
||||
if ( ! rntupleDescription ) return nullptr;
|
||||
|
||||
return rntupleDescription->fNtuple;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4int G4CsvRNtupleManager::SetNtuple(G4CsvRNtupleDescription* rntupleDescription)
|
||||
{
|
||||
G4int id = fNtupleVector.size() + fFirstId;
|
||||
|
||||
fNtupleVector.push_back(rntupleDescription);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleIColumn(const G4String& columnName,
|
||||
G4int& value)
|
||||
{
|
||||
return SetNtupleIColumn(fFirstId, columnName, value);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleFColumn(const G4String& columnName,
|
||||
G4float& value)
|
||||
{
|
||||
return SetNtupleFColumn(fFirstId, columnName, value);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleDColumn(const G4String& columnName,
|
||||
G4double& value)
|
||||
{
|
||||
return SetNtupleDColumn(fFirstId, columnName, value);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleIColumn(const G4String& columnName,
|
||||
std::vector<G4int>& vector)
|
||||
{
|
||||
return SetNtupleIColumn(fFirstId, columnName, vector);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleFColumn(const G4String& columnName,
|
||||
std::vector<G4float>& vector)
|
||||
{
|
||||
return SetNtupleFColumn(fFirstId, columnName, vector);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleDColumn(const G4String& columnName,
|
||||
std::vector<G4double>& vector)
|
||||
{
|
||||
return SetNtupleDColumn(fFirstId, columnName, vector);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleSColumn(const G4String& columnName,
|
||||
G4String& value)
|
||||
{
|
||||
return SetNtupleSColumn(fFirstId, columnName, value);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleIColumn(G4int ntupleId,
|
||||
const G4String& columnName,
|
||||
G4int& value)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL4() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL4()->Message("set", "ntuple I column", description);
|
||||
}
|
||||
#endif
|
||||
|
||||
G4CsvRNtupleDescription* ntupleDescription
|
||||
= GetNtupleInFunction(ntupleId, "SetNtupleIColumn");
|
||||
if ( ! ntupleDescription ) return false;
|
||||
|
||||
tools::ntuple_binding* ntupleBinding = ntupleDescription->fNtupleBinding;
|
||||
ntupleBinding->add_column(columnName, value);
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL2() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL2()->Message("set", "ntuple I colum", description, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleFColumn(G4int ntupleId,
|
||||
const G4String& columnName,
|
||||
G4float& value)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL4() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL4()->Message("set", "ntuple F column", description);
|
||||
}
|
||||
#endif
|
||||
|
||||
G4CsvRNtupleDescription* ntupleDescription
|
||||
= GetNtupleInFunction(ntupleId, "SetNtupleFColumn");
|
||||
if ( ! ntupleDescription ) return false;
|
||||
|
||||
tools::ntuple_binding* ntupleBinding = ntupleDescription->fNtupleBinding;
|
||||
ntupleBinding->add_column(columnName, value);
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL2() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL2()->Message("set", "ntuple F colum", description, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleDColumn(G4int ntupleId,
|
||||
const G4String& columnName,
|
||||
G4double& value)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL4() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL4()->Message("set", "ntuple D column", description);
|
||||
}
|
||||
#endif
|
||||
|
||||
G4CsvRNtupleDescription* ntupleDescription
|
||||
= GetNtupleInFunction(ntupleId, "SetNtupleDColumn");
|
||||
if ( ! ntupleDescription ) return false;
|
||||
|
||||
tools::ntuple_binding* ntupleBinding = ntupleDescription->fNtupleBinding;
|
||||
ntupleBinding->add_column(columnName, value);
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL2() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL2()->Message("set", "ntuple D colum", description, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleIColumn(G4int ntupleId,
|
||||
const G4String& columnName,
|
||||
std::vector<G4int>& vector)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL4() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL4()->Message("set", "ntuple I column", description);
|
||||
}
|
||||
#endif
|
||||
|
||||
G4CsvRNtupleDescription* ntupleDescription
|
||||
= GetNtupleInFunction(ntupleId, "SetNtupleIColumn");
|
||||
if ( ! ntupleDescription ) return false;
|
||||
|
||||
tools::ntuple_binding* ntupleBinding = ntupleDescription->fNtupleBinding;
|
||||
ntupleBinding->add_column(columnName, vector);
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL2() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL2()->Message("set", "ntuple I colum", description, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleFColumn(G4int ntupleId,
|
||||
const G4String& columnName,
|
||||
std::vector<G4float>& vector)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL4() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL4()->Message("set", "ntuple F column of vector", description);
|
||||
}
|
||||
#endif
|
||||
|
||||
G4CsvRNtupleDescription* ntupleDescription
|
||||
= GetNtupleInFunction(ntupleId, "SetNtupleFColumn");
|
||||
if ( ! ntupleDescription ) return false;
|
||||
|
||||
tools::ntuple_binding* ntupleBinding = ntupleDescription->fNtupleBinding;
|
||||
ntupleBinding->add_column(columnName, vector);
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL2() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL2()->Message("set", "ntuple F colum", description, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleDColumn(G4int ntupleId,
|
||||
const G4String& columnName,
|
||||
std::vector<G4double>& vector)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL4() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL4()->Message("set", "ntuple D column of vector", description);
|
||||
}
|
||||
#endif
|
||||
|
||||
G4CsvRNtupleDescription* ntupleDescription
|
||||
= GetNtupleInFunction(ntupleId, "SetNtupleDColumn");
|
||||
if ( ! ntupleDescription ) return false;
|
||||
|
||||
tools::ntuple_binding* ntupleBinding = ntupleDescription->fNtupleBinding;
|
||||
ntupleBinding->add_column(columnName, vector);
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL2() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL2()->Message("set", "ntuple D colum", description, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::SetNtupleSColumn(G4int ntupleId,
|
||||
const G4String& columnName,
|
||||
G4String& value)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL4() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL4()->Message("set", "ntuple S column", description);
|
||||
}
|
||||
#endif
|
||||
|
||||
G4CsvRNtupleDescription* ntupleDescription
|
||||
= GetNtupleInFunction(ntupleId, "SetNtupleSColumn");
|
||||
if ( ! ntupleDescription ) return false;
|
||||
|
||||
tools::ntuple_binding* ntupleBinding = ntupleDescription->fNtupleBinding;
|
||||
ntupleBinding->add_column(columnName, value);
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL2() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId << " " << columnName;
|
||||
fState.GetVerboseL2()->Message("set", "ntuple S colum", description, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::GetNtupleRow()
|
||||
{
|
||||
return GetNtupleRow(fFirstId);
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
G4bool G4CsvRNtupleManager::GetNtupleRow(G4int ntupleId)
|
||||
{
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL4() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId;
|
||||
fState.GetVerboseL4()->Message("get", "ntuple row", description);
|
||||
}
|
||||
#endif
|
||||
|
||||
G4CsvRNtupleDescription* ntupleDescription
|
||||
= GetNtupleInFunction(ntupleId, "GetNtupleRow");
|
||||
if ( ! ntupleDescription ) return false;
|
||||
|
||||
tools::rcsv::ntuple* ntuple = ntupleDescription->fNtuple;
|
||||
|
||||
G4bool isInitialized = ntupleDescription->fIsInitialized;
|
||||
auto isInitialized = ntupleDescription->fIsInitialized;
|
||||
if ( ! isInitialized ) {
|
||||
tools::ntuple_binding* ntupleBinding = ntupleDescription->fNtupleBinding;
|
||||
auto ntupleBinding = ntupleDescription->fNtupleBinding;
|
||||
if ( ! ntuple->initialize(G4cout, *ntupleBinding) ) {
|
||||
G4ExceptionDescription description;
|
||||
description
|
||||
@@ -428,26 +65,18 @@ G4bool G4CsvRNtupleManager::GetNtupleRow(G4int ntupleId)
|
||||
ntuple->start();
|
||||
}
|
||||
|
||||
G4bool next = ntuple->next();
|
||||
auto next = ntuple->next();
|
||||
if ( next ) {
|
||||
if ( ! ntuple->get_row() ) {
|
||||
G4ExceptionDescription description;
|
||||
description
|
||||
<< " "
|
||||
<< "Ntuple get_row() failed !!";
|
||||
G4Exception("G4CsvRNtuple::GetNtupleRow()",
|
||||
G4Exception("G4CsvRNtuple::GetTNtupleRow()",
|
||||
"Analysis_WR021", JustWarning, description);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( fState.GetVerboseL2() ) {
|
||||
G4ExceptionDescription description;
|
||||
description << " ntupleId " << ntupleId;
|
||||
fState.GetVerboseL2()->Message("get", "ntuple row", description, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ static const std::string& s_##a_name() {\
|
||||
return s_v;\
|
||||
}
|
||||
|
||||
#define TOOLS_CLASS_STRING_SVALUE(a_name,a_value)\
|
||||
static const std::string& s_##a_name() {\
|
||||
static const std::string s_v(a_value);\
|
||||
return s_v;\
|
||||
}
|
||||
|
||||
#define TOOLS_GLOBAL_STRING(a_name)\
|
||||
inline const std::string& s_##a_name() {\
|
||||
static const std::string s_v(#a_name);\
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "scast"
|
||||
#include "forit"
|
||||
#include "ntuple_binding"
|
||||
#include "mnmx"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -118,7 +119,7 @@ protected:
|
||||
m_out << s_class() << "::cstor :"
|
||||
<< " can't copy column."
|
||||
<< std::endl;
|
||||
tools::clear<base_col>(m_cols);
|
||||
safe_clear<base_col>(m_cols);
|
||||
m_index = -1;
|
||||
return; //throw
|
||||
}
|
||||
@@ -128,7 +129,7 @@ protected:
|
||||
base_ntu& operator=(const base_ntu& a_from){
|
||||
if(&a_from==this) return *this;
|
||||
|
||||
tools::clear<base_col>(m_cols);
|
||||
safe_clear<base_col>(m_cols);
|
||||
m_index = a_from.m_index;
|
||||
|
||||
m_title = a_from.m_title;
|
||||
@@ -138,7 +139,7 @@ protected:
|
||||
m_out << s_class() << "::operator=() :"
|
||||
<< " can't copy column."
|
||||
<< std::endl;
|
||||
tools::clear<base_col>(m_cols);
|
||||
safe_clear<base_col>(m_cols);
|
||||
m_index = -1;
|
||||
return *this;
|
||||
}
|
||||
@@ -150,6 +151,12 @@ protected:
|
||||
public:
|
||||
std::ostream& out() const {return m_out;}
|
||||
const std::vector<base_col*>& cols() const {return m_cols;}
|
||||
size_t columns() const {return m_cols.size();}
|
||||
|
||||
void column_names(std::vector<std::string>& a_names) const {
|
||||
a_names.clear();
|
||||
tools_vforcit(base_col*,m_cols,it) a_names.push_back((*it)->name());
|
||||
}
|
||||
|
||||
const std::string& title() const {return m_title;}
|
||||
void set_title(const std::string& a_title) {m_title = a_title;}
|
||||
@@ -160,7 +167,7 @@ public:
|
||||
}
|
||||
|
||||
void clear() { //must not be confused with reset().
|
||||
tools::clear<base_col>(m_cols);
|
||||
safe_clear<base_col>(m_cols);
|
||||
m_index = -1;
|
||||
}
|
||||
|
||||
@@ -373,6 +380,8 @@ inline bool s__fill(const std::string& a_s,double& a_v) {
|
||||
|
||||
template <class T>
|
||||
class aida_col : public aida_base_col {
|
||||
public:
|
||||
typedef T entry_t;
|
||||
public:
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::aida::aida_col<"+stype(T())+">");
|
||||
@@ -482,6 +491,8 @@ protected:
|
||||
};
|
||||
|
||||
class ntuple : public base_ntu {
|
||||
public:
|
||||
static cid id_class() {return 2000;} //for ntuple_binding.
|
||||
public:
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::aida::ntuple");
|
||||
@@ -491,6 +502,7 @@ public:
|
||||
if(void* p = cmp_cast<ntuple>(this,a_class)) {return p;}
|
||||
return base_ntu::cast(a_class);
|
||||
}
|
||||
virtual const std::string& s_cls() const {return s_class();}
|
||||
public:
|
||||
ntuple(std::ostream& a_out,const std::string& a_title)
|
||||
:base_ntu(a_out,a_title)
|
||||
@@ -529,6 +541,20 @@ public:
|
||||
return safe_cast<base_col, aida_col<T> >(*col);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool find_column(const std::string& a_name,aida_col<T>*& a_col,bool a_case_sensitive = true) { //for exlib::evaluator.
|
||||
base_col* col = a_case_sensitive ? find_named<base_col>(m_cols,a_name) : find_named_case_insensitive<base_col>(m_cols,a_name);
|
||||
if(!col) {a_col = 0;return false;}
|
||||
a_col = safe_cast<base_col, aida_col<T> >(*col);
|
||||
return a_col?true:false;
|
||||
}
|
||||
|
||||
aida_base_col* find_aida_base_column(const std::string& a_name,bool a_case_sensitive = true){ //for opaw/panntu.
|
||||
base_col* col = a_case_sensitive ? find_named<base_col>(m_cols,a_name) : find_named_case_insensitive<base_col>(m_cols,a_name);
|
||||
if(!col) return 0;
|
||||
return safe_cast<base_col,aida_base_col>(*col);
|
||||
}
|
||||
|
||||
bool get_row() const {
|
||||
bool status = true;
|
||||
tools_vforcit(base_col*,m_cols,it) {
|
||||
@@ -984,7 +1010,7 @@ inline bool create_col(ntuple& a_ntu,
|
||||
ntuple* sub_aida = safe_cast<base_ntu,ntuple>(*sub_base_ntu);
|
||||
if(!sub_aida) {delete col_ntu;return false;}
|
||||
|
||||
std::vector<value> vars = f.result();
|
||||
std::vector<value> vars;f.result(vars);
|
||||
if(!create_cols_from_vals(*sub_aida,vars)) {
|
||||
columns::delete_columns(vars);
|
||||
delete col_ntu;
|
||||
@@ -1025,7 +1051,7 @@ inline bool create_cols_from_string(ntuple& a_ntu,
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
std::vector<value> vars = f.result();
|
||||
std::vector<value> vars;f.result(vars);
|
||||
if(a_verbose) columns::dump_columns(a_ntu.out(),vars);
|
||||
|
||||
if(!create_cols_from_vals(a_ntu,vars)) {
|
||||
@@ -1201,8 +1227,8 @@ protected:
|
||||
|
||||
m_first = false;
|
||||
} else {
|
||||
m_mn = tools::mn<T>(m_mn,a_v);
|
||||
m_mx = tools::mx<T>(m_mx,a_v);
|
||||
m_mn = min_of<T>(m_mn,a_v);
|
||||
m_mx = max_of<T>(m_mx,a_v);
|
||||
m_S += a_v;
|
||||
m_S2 += a_v*a_v;
|
||||
}
|
||||
@@ -1322,6 +1348,54 @@ inline bool to_vector(base_ntu& a_ntu,std::vector<double>& a_vec,unsigned int a_
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool column_min(base_ntu& a_ntu,unsigned int a_col,T& a_value) {
|
||||
a_value = T();
|
||||
const std::vector<base_col*>& cols = a_ntu.cols();
|
||||
if(cols.empty()) return false;
|
||||
if(a_col>=cols.size()) return false;
|
||||
base_col* _base_col = cols[a_col];
|
||||
aida_col<T>* _col = safe_cast<base_col, aida_col<T> >(*_base_col);
|
||||
if(!_col) return false;
|
||||
a_ntu.start();
|
||||
uint64 _rows = a_ntu.rows();
|
||||
T v;
|
||||
{for(uint64 row=0;row<_rows;row++) {
|
||||
if(!a_ntu.next()) {a_value = T();return false;}
|
||||
if(!_col->get_entry(v)) {}
|
||||
if(!row) {
|
||||
a_value = v;
|
||||
} else {
|
||||
a_value = mn<T>(a_value,v);
|
||||
}
|
||||
}}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool column_max(base_ntu& a_ntu,unsigned int a_col,T& a_value) {
|
||||
a_value = T();
|
||||
const std::vector<base_col*>& cols = a_ntu.cols();
|
||||
if(cols.empty()) return false;
|
||||
if(a_col>=cols.size()) return false;
|
||||
base_col* _base_col = cols[a_col];
|
||||
aida_col<T>* _col = safe_cast<base_col, aida_col<T> >(*_base_col);
|
||||
if(!_col) return false;
|
||||
a_ntu.start();
|
||||
uint64 _rows = a_ntu.rows();
|
||||
T v;
|
||||
{for(uint64 row=0;row<_rows;row++) {
|
||||
if(!a_ntu.next()) {a_value = T();return false;}
|
||||
if(!_col->get_entry(v)) {}
|
||||
if(!row) {
|
||||
a_value = v;
|
||||
} else {
|
||||
a_value = mx<T>(a_value,v);
|
||||
}
|
||||
}}
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -106,6 +106,7 @@ public:
|
||||
a_value = a_def;
|
||||
return false;
|
||||
}
|
||||
#ifdef TOOLS_DEPRECATED
|
||||
std::vector<std::string> find(const std::string& a_key) const {
|
||||
std::vector<std::string> vals;
|
||||
tools_vforcit(arg,m_args,it) {
|
||||
@@ -113,6 +114,14 @@ public:
|
||||
}
|
||||
return vals;
|
||||
}
|
||||
#endif
|
||||
void find(const std::string& a_key,std::vector<std::string>& a_vals) const {
|
||||
a_vals.clear();
|
||||
tools_vforcit(arg,m_args,it) {
|
||||
if((*it).first==a_key) a_vals.push_back((*it).second);
|
||||
}
|
||||
}
|
||||
|
||||
bool find(const std::string& a_string,bool& a_value,const bool& a_def = false) const {
|
||||
std::string s;
|
||||
if(!find(a_string,s)) {a_value = a_def;return false;}
|
||||
@@ -124,6 +133,8 @@ public:
|
||||
if(!find(a_string,_s)) {a_value = a_def;return false;}
|
||||
return to<aT>(_s,a_value,a_def);
|
||||
}
|
||||
|
||||
#ifdef TOOLS_DEPRECATED
|
||||
std::vector<std::string> tovector() const {
|
||||
// Return a vector of string <name=value>
|
||||
std::vector<std::string> vec;
|
||||
@@ -140,6 +151,20 @@ public:
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
#endif
|
||||
void to_vector(std::vector<std::string>& a_vec) const {
|
||||
// Return a vector of string <name=value>
|
||||
a_vec.clear();
|
||||
std::string s;
|
||||
tools_vforcit(arg,m_args,it) {
|
||||
s = (*it).first;
|
||||
if((*it).second.size()) {
|
||||
s += "=";
|
||||
s += (*it).second;
|
||||
}
|
||||
a_vec.push_back(s);
|
||||
}
|
||||
}
|
||||
|
||||
bool add(const std::string& a_key,const std::string& a_value = "",bool a_override = true){
|
||||
if(a_override) {
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_buf2lines
|
||||
#define tools_buf2lines
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace tools {
|
||||
|
||||
inline void buf2lines(char* a_buffer,std::vector<std::string>& a_lines) {
|
||||
// WARNING : it is assumed that last char of a_buffer is 0.
|
||||
// This function seeks '\n' and replaces them with '0'.
|
||||
a_lines.clear();
|
||||
char* pos = a_buffer;
|
||||
char* beg = pos;
|
||||
while(true) {
|
||||
if((*pos=='\r')&&(*(pos+1)=='\n')) {
|
||||
*pos = 0;
|
||||
a_lines.push_back(beg);
|
||||
pos += 2;
|
||||
beg = pos;
|
||||
} else if(*pos=='\n') {
|
||||
*pos = 0;
|
||||
a_lines.push_back(beg);
|
||||
pos++;
|
||||
beg = pos;
|
||||
} else if(*pos==0) {
|
||||
a_lines.push_back(beg);
|
||||
return;
|
||||
} else {
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include <string.h> //memcpy
|
||||
|
||||
namespace tools {
|
||||
|
||||
// used in exlib/hdf5/T_tools,tools :
|
||||
/*
|
||||
inline bool strings2buf(size_t a_number,const char** a_strings,size_t& a_size,char*& a_buffer) {
|
||||
// For {"aa","bbb"}, it produces "aa0bbb00".
|
||||
// For {""}, it produces "00".
|
||||
// For {}, it produces "0".
|
||||
a_size = 0;
|
||||
for(size_t index=0;index<a_number;index++) a_size += ::strlen(a_strings[index])+1;
|
||||
a_size++;
|
||||
a_buffer = new char[a_size];
|
||||
if(!a_buffer) {a_size = 0;return false;}
|
||||
char* pos = a_buffer;
|
||||
size_t array_size;
|
||||
for(size_t index=0;index<a_number;index++) {
|
||||
const char* s = a_strings[index];
|
||||
array_size = ::strlen(s)+1;
|
||||
::memcpy(pos,s,array_size);
|
||||
pos += array_size;
|
||||
}
|
||||
*pos = '\0';
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
inline bool strings2buf(const std::vector<std::string>& a_strings,size_t& a_size,char*& a_buffer) {
|
||||
// For {"aa","bbb"}, it produces "aa0bbb00".
|
||||
// For {""}, it produces "00".
|
||||
// For {}, it produces "0".
|
||||
size_t number = a_strings.size();
|
||||
a_size = 0;
|
||||
for(size_t index=0;index<number;index++) a_size += a_strings[index].size()+1;
|
||||
a_size++;
|
||||
a_buffer = new char[a_size];
|
||||
if(!a_buffer) {a_size = 0;return false;}
|
||||
char* pos = a_buffer;
|
||||
size_t array_size;
|
||||
for(size_t index=0;index<number;index++) {
|
||||
const std::string& s = a_strings[index];
|
||||
array_size = s.size()+1;
|
||||
::memcpy(pos,s.c_str(),array_size);
|
||||
pos += array_size;
|
||||
}
|
||||
*pos = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool buf2strings(size_t a_size,char* a_buffer,std::vector<std::string>& a_strings) {
|
||||
if(a_size<=1) return false;
|
||||
// We assume here a_size>=1
|
||||
// Exa : if ab0cde00, then a_strings should contain two strings ab and cde.
|
||||
a_strings.clear();
|
||||
char* begin = a_buffer;
|
||||
char* pos = a_buffer;
|
||||
size_t number = a_size-1;
|
||||
for(size_t index=0;index<number;index++) {
|
||||
if((*pos)=='\0') {
|
||||
size_t l = pos - begin;
|
||||
std::string s(l,0);
|
||||
char* data = (char*)s.c_str();
|
||||
::memcpy(data,begin,l);
|
||||
a_strings.push_back(s);
|
||||
begin = pos+1;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
//pos++;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,668 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_ccontour
|
||||
#define tools_ccontour
|
||||
|
||||
// G.Barrand : inline version of the one found in Lib of OSC 16.11.
|
||||
// This code is not mine and I keep it "as it is".
|
||||
|
||||
// Contour.h: interface for the ccontour class.
|
||||
//
|
||||
// ccontour implements Contour plot algorithm descrided in
|
||||
// IMPLEMENTATION OF
|
||||
// AN IMPROVED CONTOUR
|
||||
// PLOTTING ALGORITHM
|
||||
// BY
|
||||
//
|
||||
// MICHAEL JOSEPH ARAMINI
|
||||
//
|
||||
// B.S., Stevens Institute of Technology, 1980
|
||||
// See http://www.ultranet.com/~aramini/thesis.html
|
||||
//
|
||||
// Ported to C++ by Jonathan de Halleux.
|
||||
//
|
||||
// Using ccontour :
|
||||
//
|
||||
// ccontour is not directly usable. The user has to
|
||||
// 1. derive the function ExportLine that is
|
||||
// supposed to draw/store the segment of the contour
|
||||
// 2. Set the function draw contour of. (using SetFieldFn
|
||||
// The function must be declared as follows
|
||||
// double (*myF)(double x , double y);
|
||||
//
|
||||
// History:
|
||||
// 31-07-2002:
|
||||
// - A lot of contribution from Chenggang Zhou (better strip compressions, merging, area, weight),
|
||||
// - Got rid of ugly MFC lists for STL.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//G.Barrand :
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
#include "mem"
|
||||
#endif
|
||||
|
||||
#include "mnmx"
|
||||
|
||||
namespace tools {
|
||||
|
||||
class ccontour
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::ccontour");
|
||||
return s_v;
|
||||
}
|
||||
#endif
|
||||
protected:
|
||||
// plots a line from (x1,y1) to (x2,y2)
|
||||
virtual void ExportLine(int iPlane,int x1,int y1,int x2,int y2) = 0;
|
||||
|
||||
public:
|
||||
ccontour();
|
||||
virtual ~ccontour(){
|
||||
CleanMemory();
|
||||
#ifdef TOOLS_MEM
|
||||
mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected: //G.Barrand
|
||||
ccontour(const ccontour&){}
|
||||
private: //G.Barrand
|
||||
ccontour& operator=(const ccontour&){return *this;}
|
||||
public:
|
||||
protected: //G.Barrand
|
||||
// Initialize memory. Called in generate
|
||||
virtual void InitMemory();
|
||||
// Clean work arrays
|
||||
virtual void CleanMemory();
|
||||
// generates contour
|
||||
// Before calling this functions you must
|
||||
// 1. derive the function ExportLine that is
|
||||
// supposed to draw/store the segment of the contour
|
||||
// 2. Set the function draw contour of. (using SetFieldFn
|
||||
// The function must be declared as follows
|
||||
// double (*myF)(double x , double y);
|
||||
public: //G.Barrand
|
||||
virtual void generate();
|
||||
|
||||
// Set the dimension of the primary grid
|
||||
void set_first_grid(int iCol, int iRow);
|
||||
// Set the dimension of the base grid
|
||||
void set_secondary_grid(int iCol, int iRow);
|
||||
// Sets the region [left, right, bottom,top] to generate contour
|
||||
void set_limits(double pLimits[4]);
|
||||
// Sets the isocurve values
|
||||
void set_planes(const std::vector<double>& vPlanes);
|
||||
// Sets the pointer to the F(x,y) funtion
|
||||
// G.Barrand : handle a user data pointer.
|
||||
void set_field_fcn(double (*_pFieldFcn)(double, double,void*),void*);
|
||||
|
||||
size_t get_number_of_planes() const { return m_vPlanes.size();};
|
||||
const std::vector<double>& get_planes() const { return m_vPlanes;};
|
||||
double get_plane(unsigned int i) const;
|
||||
|
||||
// For an indexed point i on the sec. grid, returns x(i)
|
||||
double get_xi(int i) const { return m_pLimits[0] + i%(m_iColSec+1)*(m_pLimits[1]-m_pLimits[0])/(double)( m_iColSec );};
|
||||
// For an indexed point i on the fir. grid, returns y(i)
|
||||
double get_yi(int i) const;
|
||||
|
||||
void get_limits(double pLimits[4]);
|
||||
protected: //G.Barrand
|
||||
|
||||
// Retrieve dimension of grids, contouring region and isocurve
|
||||
int GetColFir() const { return m_iColFir;};
|
||||
int GetRowFir() const { return m_iRowFir;};
|
||||
int GetColSec() const { return m_iColSec;};
|
||||
int GetRowSec() const { return m_iRowSec;};
|
||||
|
||||
private:
|
||||
// A structure used internally by ccontour
|
||||
/*G.Barrand :
|
||||
struct CFnStr {
|
||||
double m_dFnVal;
|
||||
short m_sLeftLen;
|
||||
short m_sRightLen;
|
||||
short m_sTopLen;
|
||||
short m_sBotLen;
|
||||
};
|
||||
*/
|
||||
class CFnStr {
|
||||
#ifdef TOOLS_MEM
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::ccontour::CFnStr");
|
||||
return s_v;
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
CFnStr():m_dFnVal(0),m_sLeftLen(0),m_sRightLen(0),m_sTopLen(0),m_sBotLen(0){
|
||||
#ifdef TOOLS_MEM
|
||||
mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
~CFnStr(){
|
||||
#ifdef TOOLS_MEM
|
||||
mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected:
|
||||
CFnStr(const CFnStr&){}
|
||||
CFnStr& operator=(const CFnStr&){return *this;}
|
||||
public:
|
||||
double m_dFnVal;
|
||||
short m_sLeftLen;
|
||||
short m_sRightLen;
|
||||
short m_sTopLen;
|
||||
short m_sBotLen;
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
// Accesibles variables
|
||||
std::vector<double> m_vPlanes; // value of contour planes
|
||||
double m_pLimits[4]; // left, right, bottom, top
|
||||
int m_iColFir; // primary grid, number of columns
|
||||
int m_iRowFir; // primary grid, number of rows
|
||||
int m_iColSec; // secondary grid, number of columns
|
||||
int m_iRowSec; // secondary grid, number of rows
|
||||
void* m_pFieldFcnData; // G.Barrand : handle a user data pointer.
|
||||
double (*m_pFieldFcn)(double x, double y,void*); // pointer to F(x,y) function
|
||||
|
||||
// Protected function
|
||||
//virtual void ExportLine(int iPlane, int x1, int y1, int x2, int y2) = 0; // plots a line from (x1,y1) to (x2,y2)
|
||||
|
||||
// Work functions and variables
|
||||
double m_dDx;
|
||||
double m_dDy;
|
||||
CFnStr** m_ppFnData; // pointer to mesh parts
|
||||
CFnStr* FnctData(int i,int j) { return (m_ppFnData[i]+j);};
|
||||
|
||||
double Field(int x, int y); /* evaluate funct if we must, */
|
||||
void Cntr1(int x1, int x2, int y1, int y2);
|
||||
void Pass2(int x1, int x2, int y1, int y2); /* draws the contour lines */
|
||||
|
||||
private:
|
||||
//G.Barrand : have the below in the class.
|
||||
// A simple test function
|
||||
static double ContourTestFunction(double x,double y,void*) {
|
||||
return 0.5*(::cos(x+3.14/4)+::sin(y+3.14/4));
|
||||
}
|
||||
|
||||
protected:
|
||||
static void _ASSERT_(bool a_what,const char* a_where) {
|
||||
if(!a_what) {
|
||||
::printf("debug : Contour : assert failure in %s\n",a_where);
|
||||
::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void _ASSERTP_(void* a_what,const char* a_where) {
|
||||
if(!a_what) {
|
||||
::printf("debug : Contour : assert failure in %s\n",a_where);
|
||||
::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// implementation :
|
||||
//
|
||||
// Code get on the web at :
|
||||
// http://www.codeproject.com/cpp/contour.asp
|
||||
//
|
||||
// G.Barrand
|
||||
//
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline ccontour::ccontour()
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
mem::increment(s_class().c_str());
|
||||
#endif
|
||||
m_iColFir=m_iRowFir=32;
|
||||
m_iColSec=m_iRowSec=256;
|
||||
m_dDx=m_dDy=0;
|
||||
m_pFieldFcnData = NULL;
|
||||
m_pFieldFcn=NULL;
|
||||
m_pLimits[0]=m_pLimits[2]=0;
|
||||
m_pLimits[1]=m_pLimits[3]=5.;
|
||||
m_ppFnData=NULL;
|
||||
|
||||
// temporary stuff
|
||||
m_pFieldFcn=ContourTestFunction;
|
||||
m_vPlanes.resize(20);
|
||||
for (unsigned int i=0;i<m_vPlanes.size();i++)
|
||||
{
|
||||
m_vPlanes[i]=(i-m_vPlanes.size()/2.0)*0.1;
|
||||
}
|
||||
}
|
||||
|
||||
//G.Barrand : inline
|
||||
|
||||
inline void ccontour::InitMemory()
|
||||
{
|
||||
if (!m_ppFnData)
|
||||
{
|
||||
m_ppFnData=new CFnStr*[m_iColSec+1];
|
||||
for (int i=0;i<m_iColSec+1;i++)
|
||||
{
|
||||
m_ppFnData[i]=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void ccontour::CleanMemory()
|
||||
{
|
||||
if (m_ppFnData)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<m_iColSec+1;i++)
|
||||
{
|
||||
if (m_ppFnData[i])
|
||||
delete[] (m_ppFnData[i]);
|
||||
}
|
||||
delete[] m_ppFnData;
|
||||
m_ppFnData=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inline void ccontour::generate()
|
||||
{
|
||||
|
||||
int i, j;
|
||||
int x3, x4, y3, y4, x, y, oldx3, xlow;
|
||||
const int cols=m_iColSec+1;
|
||||
const int rows=m_iRowSec+1;
|
||||
//double xoff,yoff;
|
||||
|
||||
// Initialize memroy if needed
|
||||
InitMemory();
|
||||
|
||||
m_dDx = (m_pLimits[1]-m_pLimits[0])/(double)(m_iColSec);
|
||||
//xoff = m_pLimits[0];
|
||||
m_dDy = (m_pLimits[3]-m_pLimits[2])/(double)(m_iRowSec);
|
||||
//yoff = m_pLimits[2];
|
||||
|
||||
xlow = 0;
|
||||
oldx3 = 0;
|
||||
x3 = (cols-1)/m_iRowFir;
|
||||
x4 = ( 2*(cols-1) )/m_iRowFir;
|
||||
for (x = oldx3; x <= x4; x++)
|
||||
{ /* allocate new columns needed
|
||||
*/
|
||||
if (x >= cols)
|
||||
break;
|
||||
if (m_ppFnData[x]==NULL)
|
||||
m_ppFnData[x] = new CFnStr[rows];
|
||||
|
||||
for (y = 0; y < rows; y++)
|
||||
FnctData(x,y)->m_sTopLen = -1;
|
||||
}
|
||||
|
||||
y4 = 0;
|
||||
for (j = 0; j < m_iColFir; j++)
|
||||
{
|
||||
y3 = y4;
|
||||
y4 = ((j+1)*(rows-1))/m_iColFir;
|
||||
Cntr1(oldx3, x3, y3, y4);
|
||||
}
|
||||
|
||||
for (i = 1; i < m_iRowFir; i++)
|
||||
{
|
||||
y4 = 0;
|
||||
for (j = 0; j < m_iColFir; j++)
|
||||
{
|
||||
y3 = y4;
|
||||
y4 = ((j+1)*(rows-1))/m_iColFir;
|
||||
Cntr1(x3, x4, y3, y4);
|
||||
}
|
||||
|
||||
y4 = 0;
|
||||
for (j = 0; j < m_iColFir; j++)
|
||||
{
|
||||
y3 = y4;
|
||||
y4 = ((j+1)*(rows-1))/m_iColFir;
|
||||
Pass2(oldx3,x3,y3,y4);
|
||||
}
|
||||
|
||||
if (i < (m_iRowFir-1))
|
||||
{ /* re-use columns no longer needed */
|
||||
oldx3 = x3;
|
||||
x3 = x4;
|
||||
x4 = ((i+2)*(cols-1))/m_iRowFir;
|
||||
for (x = x3+1; x <= x4; x++)
|
||||
{
|
||||
if (xlow < oldx3)
|
||||
{
|
||||
if (m_ppFnData[x])
|
||||
delete[] m_ppFnData[x];
|
||||
m_ppFnData[x] = m_ppFnData[xlow];
|
||||
m_ppFnData[ xlow++ ] = NULL;
|
||||
}
|
||||
else
|
||||
if (m_ppFnData[x]==NULL)
|
||||
m_ppFnData[x] = new CFnStr[rows];
|
||||
|
||||
for (y = 0; y < rows; y++)
|
||||
FnctData(x,y)->m_sTopLen = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
y4 = 0;
|
||||
for (j = 0; j < m_iColFir; j++)
|
||||
{
|
||||
y3 = y4;
|
||||
y4 = ((j+1)*(rows-1))/m_iColFir;
|
||||
Pass2(x3,x4,y3,y4);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ccontour::Cntr1(int x1, int x2, int y1, int y2)
|
||||
{
|
||||
double f11, f12, f21, f22, f33;
|
||||
int x3, y3, i, j;
|
||||
|
||||
if ((x1 == x2) || (y1 == y2)) /* if not a real cell, punt */
|
||||
return;
|
||||
f11 = Field(x1, y1);
|
||||
f12 = Field(x1, y2);
|
||||
f21 = Field(x2, y1);
|
||||
f22 = Field(x2, y2);
|
||||
if ((x2 > x1+1) || (y2 > y1+1)) { /* is cell divisible? */
|
||||
x3 = (x1+x2)/2;
|
||||
y3 = (y1+y2)/2;
|
||||
f33 = Field(x3, y3);
|
||||
i = j = 0;
|
||||
if (f33 < f11) i++; else if (f33 > f11) j++;
|
||||
if (f33 < f12) i++; else if (f33 > f12) j++;
|
||||
if (f33 < f21) i++; else if (f33 > f21) j++;
|
||||
if (f33 < f22) i++; else if (f33 > f22) j++;
|
||||
if ((i > 2) || (j > 2)) /* should we divide cell? */
|
||||
{
|
||||
/* subdivide cell */
|
||||
Cntr1(x1, x3, y1, y3);
|
||||
Cntr1(x3, x2, y1, y3);
|
||||
Cntr1(x1, x3, y3, y2);
|
||||
Cntr1(x3, x2, y3, y2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* install cell in array */
|
||||
FnctData(x1,y2)->m_sBotLen = FnctData(x1,y1)->m_sTopLen = x2-x1;
|
||||
FnctData(x2,y1)->m_sLeftLen = FnctData(x1,y1)->m_sRightLen = y2-y1;
|
||||
}
|
||||
|
||||
inline void ccontour::Pass2(int x1, int x2, int y1, int y2)
|
||||
{
|
||||
int left = 0, right = 0, top = 0, bot = 0,old, iNew, i, j, x3, y3;
|
||||
double yy0 = 0, yy1 = 0, xx0 = 0, xx1 = 0, xx3, yy3;
|
||||
double v, f11, f12, f21, f22, f33, fold, fnew, f;
|
||||
double xoff=m_pLimits[0];
|
||||
double yoff=m_pLimits[2];
|
||||
|
||||
if ((x1 == x2) || (y1 == y2)) /* if not a real cell, punt */
|
||||
return;
|
||||
f11 = FnctData(x1,y1)->m_dFnVal;
|
||||
f12 = FnctData(x1,y2)->m_dFnVal;
|
||||
f21 = FnctData(x2,y1)->m_dFnVal;
|
||||
f22 = FnctData(x2,y2)->m_dFnVal;
|
||||
if ((x2 > x1+1) || (y2 > y1+1)) /* is cell divisible? */
|
||||
{
|
||||
x3 = (x1+x2)/2;
|
||||
y3 = (y1+y2)/2;
|
||||
f33 = FnctData(x3, y3)->m_dFnVal;
|
||||
i = j = 0;
|
||||
if (f33 < f11) i++; else if (f33 > f11) j++;
|
||||
if (f33 < f12) i++; else if (f33 > f12) j++;
|
||||
if (f33 < f21) i++; else if (f33 > f21) j++;
|
||||
if (f33 < f22) i++; else if (f33 > f22) j++;
|
||||
if ((i > 2) || (j > 2)) /* should we divide cell? */
|
||||
{
|
||||
/* subdivide cell */
|
||||
Pass2(x1, x3, y1, y3);
|
||||
Pass2(x3, x2, y1, y3);
|
||||
Pass2(x1, x3, y3, y2);
|
||||
Pass2(x3, x2, y3, y2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)m_vPlanes.size(); i++)
|
||||
{
|
||||
v = m_vPlanes[i];
|
||||
j = 0;
|
||||
if (f21 > v) j++;
|
||||
if (f11 > v) j |= 2;
|
||||
if (f22 > v) j |= 4;
|
||||
if (f12 > v) j |= 010;
|
||||
if ((f11 > v) ^ (f12 > v))
|
||||
{
|
||||
if ((FnctData(x1,y1)->m_sLeftLen != 0) &&
|
||||
(FnctData(x1,y1)->m_sLeftLen < FnctData(x1,y1)->m_sRightLen))
|
||||
{
|
||||
old = y1;
|
||||
fold = f11;
|
||||
while (1)
|
||||
{
|
||||
iNew = old+FnctData(x1,old)->m_sLeftLen;
|
||||
fnew = FnctData(x1,iNew)->m_dFnVal;
|
||||
if ((fnew > v) ^ (fold > v))
|
||||
break;
|
||||
old = iNew;
|
||||
fold = fnew;
|
||||
}
|
||||
yy0 = ((old-y1)+(iNew-old)*(v-fold)/(fnew-fold))/(y2-y1);
|
||||
}
|
||||
else
|
||||
yy0 = (v-f11)/(f12-f11);
|
||||
|
||||
left = (int)(y1+(y2-y1)*yy0+0.5);
|
||||
}
|
||||
if ((f21 > v) ^ (f22 > v))
|
||||
{
|
||||
if ((FnctData(x2,y1)->m_sRightLen != 0) &&
|
||||
(FnctData(x2,y1)->m_sRightLen < FnctData(x2,y1)->m_sLeftLen))
|
||||
{
|
||||
old = y1;
|
||||
fold = f21;
|
||||
while (1)
|
||||
{
|
||||
iNew = old+FnctData(x2,old)->m_sRightLen;
|
||||
fnew = FnctData(x2,iNew)->m_dFnVal;
|
||||
if ((fnew > v) ^ (fold > v))
|
||||
break;
|
||||
old = iNew;
|
||||
fold = fnew;
|
||||
}
|
||||
yy1 = ((old-y1)+(iNew-old)*(v-fold)/(fnew-fold))/(y2-y1);
|
||||
}
|
||||
else
|
||||
yy1 = (v-f21)/(f22-f21);
|
||||
|
||||
right = (int)(y1+(y2-y1)*yy1+0.5);
|
||||
}
|
||||
if ((f21 > v) ^ (f11 > v))
|
||||
{
|
||||
if ((FnctData(x1,y1)->m_sBotLen != 0) &&
|
||||
(FnctData(x1,y1)->m_sBotLen < FnctData(x1,y1)->m_sTopLen)) {
|
||||
old = x1;
|
||||
fold = f11;
|
||||
while (1) {
|
||||
iNew = old+FnctData(old,y1)->m_sBotLen;
|
||||
fnew = FnctData(iNew,y1)->m_dFnVal;
|
||||
if ((fnew > v) ^ (fold > v))
|
||||
break;
|
||||
old = iNew;
|
||||
fold = fnew;
|
||||
}
|
||||
xx0 = ((old-x1)+(iNew-old)*(v-fold)/(fnew-fold))/(x2-x1);
|
||||
}
|
||||
else
|
||||
xx0 = (v-f11)/(f21-f11);
|
||||
|
||||
bot = (int)(x1+(x2-x1)*xx0+0.5);
|
||||
}
|
||||
if ((f22 > v) ^ (f12 > v))
|
||||
{
|
||||
if ((FnctData(x1,y2)->m_sTopLen != 0) &&
|
||||
(FnctData(x1,y2)->m_sTopLen < FnctData(x1,y2)->m_sBotLen)) {
|
||||
old = x1;
|
||||
fold = f12;
|
||||
while (1) {
|
||||
iNew = old+FnctData(old,y2)->m_sTopLen;
|
||||
fnew = FnctData(iNew,y2)->m_dFnVal;
|
||||
if ((fnew > v) ^ (fold > v))
|
||||
break;
|
||||
old = iNew;
|
||||
fold = fnew;
|
||||
}
|
||||
xx1 = ((old-x1)+(iNew-old)*(v-fold)/(fnew-fold))/(x2-x1);
|
||||
}
|
||||
else
|
||||
xx1 = (v-f12)/(f22-f12);
|
||||
|
||||
top = (int)(x1+(x2-x1)*xx1+0.5);
|
||||
}
|
||||
|
||||
switch (j)
|
||||
{
|
||||
case 7:
|
||||
case 010:
|
||||
ExportLine(i,x1,left,top,y2);
|
||||
break;
|
||||
case 5:
|
||||
case 012:
|
||||
ExportLine(i,bot,y1,top,y2);
|
||||
break;
|
||||
case 2:
|
||||
case 015:
|
||||
ExportLine(i,x1,left,bot,y1);
|
||||
break;
|
||||
case 4:
|
||||
case 013:
|
||||
ExportLine(i,top,y2,x2,right);
|
||||
break;
|
||||
case 3:
|
||||
case 014:
|
||||
ExportLine(i,x1,left,x2,right);
|
||||
break;
|
||||
case 1:
|
||||
case 016:
|
||||
ExportLine(i,bot,y1,x2,right);
|
||||
break;
|
||||
case 0:
|
||||
case 017:
|
||||
break;
|
||||
case 6:
|
||||
case 011:
|
||||
yy3 = (xx0*(yy1-yy0)+yy0)/(1.0-(xx1-xx0)*(yy1-yy0));
|
||||
xx3 = yy3*(xx1-xx0)+xx0;
|
||||
xx3 = x1+xx3*(x2-x1);
|
||||
yy3 = y1+yy3*(y2-y1);
|
||||
xx3 = xoff+xx3*m_dDx;
|
||||
yy3 = yoff+yy3*m_dDy;
|
||||
f = (*m_pFieldFcn)(xx3, yy3,m_pFieldFcnData);
|
||||
if (f == v) {
|
||||
ExportLine(i,bot,y1,top,y2);
|
||||
ExportLine(i,x1,left,x2,right);
|
||||
} else
|
||||
if (((f > v) && (f22 > v)) || ((f < v) && (f22 < v))) {
|
||||
ExportLine(i,x1,left,top,y2);
|
||||
ExportLine(i,bot,y1,x2,right);
|
||||
} else {
|
||||
ExportLine(i,x1,left,bot,y1);
|
||||
ExportLine(i,top,y2,x2,right);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline double ccontour::Field(int x, int y) /* evaluate funct if we must,*/
|
||||
{
|
||||
double x1, y1;
|
||||
|
||||
if (FnctData(x,y)->m_sTopLen != -1) /* is it already in the array */
|
||||
return(FnctData(x,y)->m_dFnVal);
|
||||
|
||||
/* not in the array, create new array element */
|
||||
x1 = m_pLimits[0]+m_dDx*x;
|
||||
y1 = m_pLimits[2]+m_dDy*y;
|
||||
FnctData(x,y)->m_sTopLen = 0;
|
||||
FnctData(x,y)->m_sBotLen = 0;
|
||||
FnctData(x,y)->m_sRightLen = 0;
|
||||
FnctData(x,y)->m_sLeftLen = 0;
|
||||
return (FnctData(x,y)->m_dFnVal = (*m_pFieldFcn)(x1, y1,m_pFieldFcnData));
|
||||
}
|
||||
|
||||
inline void ccontour::set_planes(const std::vector<double>& vPlanes)
|
||||
{
|
||||
// cleaning memory
|
||||
CleanMemory();
|
||||
|
||||
m_vPlanes = vPlanes;
|
||||
}
|
||||
|
||||
inline void ccontour::set_field_fcn(double (*_pFieldFcn)(double, double,void*),void* aData)
|
||||
{
|
||||
m_pFieldFcnData = aData;
|
||||
m_pFieldFcn=_pFieldFcn;
|
||||
}
|
||||
|
||||
inline void ccontour::set_first_grid(int iCol, int iRow)
|
||||
{
|
||||
m_iColFir=mx<int>(iCol,2);
|
||||
m_iRowFir=mx<int>(iRow,2);
|
||||
}
|
||||
|
||||
inline void ccontour::set_secondary_grid(int iCol, int iRow)
|
||||
{
|
||||
// cleaning work matrices if allocated
|
||||
CleanMemory();
|
||||
|
||||
m_iColSec=mx<int>(iCol,2);
|
||||
m_iRowSec=mx<int>(iRow,2);
|
||||
}
|
||||
|
||||
inline void ccontour::set_limits(double pLimits[])
|
||||
{
|
||||
_ASSERT_(pLimits[0]<pLimits[1],"ccontour::set_limits");
|
||||
_ASSERT_(pLimits[2]<pLimits[3],"ccontour::set_limits");
|
||||
for (int i=0;i<4;i++)
|
||||
{
|
||||
m_pLimits[i]=pLimits[i];
|
||||
}
|
||||
}
|
||||
|
||||
inline void ccontour::get_limits(double pLimits[])
|
||||
{
|
||||
for (int i=0;i<4;i++)
|
||||
{
|
||||
pLimits[i]=m_pLimits[i];
|
||||
}
|
||||
}
|
||||
|
||||
//G.Barrand : from .h to .cxx to avoid _ASSERT_ in .h
|
||||
inline double ccontour::get_plane(unsigned int i) const {
|
||||
/*_ASSERT_(i>=0);*/
|
||||
_ASSERT_(i<m_vPlanes.size(),"ccontour::get_plane");
|
||||
return m_vPlanes[i];
|
||||
}
|
||||
|
||||
inline double ccontour::get_yi(int i) const {
|
||||
if(i<0) ::printf("ccontour::get_yi : %d\n",i);
|
||||
_ASSERT_(i>=0,"ccontour::get_yi");
|
||||
return m_pLimits[2] + i/(m_iColSec+1)*(m_pLimits[3]-m_pLimits[2])/(double)( m_iRowSec );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -48,7 +48,10 @@ template <class T>
|
||||
inline cid _cid(const std::vector<T>&) {return 20+_cid(T());}
|
||||
|
||||
template <class T>
|
||||
inline cid _cid_std_vector() {return 20+_cid(T());}
|
||||
inline cid _cid_std_vector() {
|
||||
static const T s_v = T(); //do that for T = std::string.
|
||||
return 20+_cid(s_v);
|
||||
}
|
||||
|
||||
// Then : cid for std::vector< std::vector<T> > is going to be :
|
||||
// 20+_cid(std::vector<T>) = 2*20+_cid(T)
|
||||
|
||||
@@ -0,0 +1,893 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_clist_contour
|
||||
#define tools_clist_contour
|
||||
|
||||
// G.Barrand : inline version of the one found in Lib of OSC 16.11.
|
||||
// This code is not mine and I keep it "as it is".
|
||||
|
||||
// Inheritance :
|
||||
#include "ccontour"
|
||||
|
||||
#include <list>
|
||||
#include <ostream>
|
||||
#include <iomanip> //std::setprecision
|
||||
|
||||
namespace tools {
|
||||
|
||||
// a list of point index referring to the secondary grid
|
||||
// Let i the index of a point,
|
||||
typedef std::list<unsigned int> cline_strip;
|
||||
typedef std::list<cline_strip*> cline_strip_list;
|
||||
typedef std::vector<cline_strip_list> cline_strip_list_vector;
|
||||
|
||||
class clist_contour : public ccontour
|
||||
{
|
||||
public: //ccontour
|
||||
// Adding segment to line strips
|
||||
// See ccontour::ExportLine for further details
|
||||
virtual void ExportLine(int iPlane,int x1, int y1, int x2, int y2);
|
||||
|
||||
public:
|
||||
clist_contour();
|
||||
virtual ~clist_contour(){CleanMemory();}
|
||||
protected: //G.Barrand
|
||||
clist_contour(const clist_contour& a_from):ccontour(a_from){}
|
||||
private: //G.Barrand
|
||||
clist_contour& operator=(const clist_contour&){return *this;}
|
||||
public:
|
||||
// retreiving list of line strip for the i-th contour
|
||||
cline_strip_list* get_lines(unsigned int iPlane);
|
||||
// Basic algorithm to concatanate line strip. Not optimized at all !
|
||||
bool compact_strips ();
|
||||
// generate contour strips
|
||||
virtual void generate();
|
||||
protected: //G.Barrand
|
||||
|
||||
// Initializing memory
|
||||
virtual void InitMemory();
|
||||
// Cleaning memory and line strips
|
||||
virtual void CleanMemory();
|
||||
|
||||
// Adding segment to line strips
|
||||
// See ccontour::ExportLine for further details
|
||||
//void ExportLine(int iPlane,int x1, int y1, int x2, int y2);
|
||||
|
||||
/// debuggin
|
||||
void DumpPlane(unsigned int iPlane) const;
|
||||
|
||||
// Area given by this function can be positive or negative depending on the winding direction of the contour.
|
||||
double Area(cline_strip* Line);
|
||||
|
||||
double EdgeWeight(cline_strip* pLine, double R);
|
||||
//bool PrintContour(std::ostream& a_out);
|
||||
protected:
|
||||
// Merges pStrip1 with pStrip2 if they have a common end point
|
||||
bool MergeStrips(cline_strip* pStrip1, cline_strip* pStrip2);
|
||||
// Merges the two strips with a welding threshold.
|
||||
bool ForceMerge(cline_strip* pStrip1, cline_strip* pStrip2,double);
|
||||
// returns true if contour is touching boundary
|
||||
bool OnBoundary(cline_strip* pStrip);
|
||||
// L.Garnier : check specials case for CompactStrip
|
||||
bool SpecialCompactStripCase(double,double,double,double,double);
|
||||
|
||||
private:
|
||||
// array of line strips
|
||||
cline_strip_list_vector m_vStripLists;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
private:
|
||||
static const char* _TT(const char* what) {return what;}
|
||||
|
||||
static void _TRACE_(const char* /*a_fmt*/,...) {
|
||||
//va_list args;
|
||||
//va_start(args,a_fmt);
|
||||
//::vprintf(s,a_fmt,args);
|
||||
//va_end(args);
|
||||
}
|
||||
static void _PROBLEM_(const char* what) {::printf("%s",what);}
|
||||
|
||||
static bool _ASSERT_RET_(bool what,const char* cmt) {
|
||||
if(!(what)) {
|
||||
::printf("debug : ListContour : assert failure in %s\n",cmt);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _ASSERT_MERGE_RET_(bool what,const char* cmt,cline_strip* pStrip2) {
|
||||
if(!(what)) {
|
||||
::printf("debug : ListContour : assert failure in %s\n",cmt);
|
||||
pStrip2->clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// implementation :
|
||||
inline clist_contour::clist_contour()
|
||||
: ccontour()
|
||||
{
|
||||
}
|
||||
|
||||
inline void clist_contour::generate()
|
||||
{
|
||||
// generate line strips
|
||||
ccontour::generate();
|
||||
// compact strips
|
||||
compact_strips ();
|
||||
}
|
||||
|
||||
inline void clist_contour::InitMemory()
|
||||
{
|
||||
ccontour::InitMemory();
|
||||
|
||||
cline_strip_list::iterator pos;
|
||||
cline_strip* pStrip;
|
||||
|
||||
if (!m_vStripLists.empty())
|
||||
{
|
||||
UINT i;
|
||||
// reseting lists
|
||||
_ASSERT_(m_vStripLists.size() == get_number_of_planes(),"clist_contour::InitMemory::0");
|
||||
for (i=0;i<get_number_of_planes();i++)
|
||||
{
|
||||
for (pos = m_vStripLists[i].begin(); pos!=m_vStripLists[i].end() ; pos++)
|
||||
{
|
||||
pStrip=(*pos);
|
||||
_ASSERTP_(pStrip,"clist_contour::InitMemory::1");
|
||||
|
||||
pStrip->clear();
|
||||
delete pStrip;
|
||||
}
|
||||
m_vStripLists[i].clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
m_vStripLists.resize(get_number_of_planes());
|
||||
}
|
||||
|
||||
inline void clist_contour::CleanMemory()
|
||||
{
|
||||
ccontour::CleanMemory();
|
||||
|
||||
cline_strip_list::iterator pos;
|
||||
cline_strip* pStrip;
|
||||
UINT i;
|
||||
|
||||
// reseting lists
|
||||
for (i=0;i<m_vStripLists.size();i++) //G.Barrand
|
||||
{
|
||||
for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++)
|
||||
{
|
||||
pStrip=(*pos);
|
||||
_ASSERTP_(pStrip,"clist_contour::CleanMemory");
|
||||
pStrip->clear();
|
||||
delete pStrip;
|
||||
}
|
||||
m_vStripLists[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
inline void clist_contour::ExportLine(int iPlane,int x1, int y1, int x2, int y2)
|
||||
{
|
||||
_ASSERT_(iPlane>=0,"clist_contour::ExportLine::0");
|
||||
_ASSERT_(iPlane<(int)get_number_of_planes(),"clist_contour::ExportLine::1");
|
||||
|
||||
// check that the two points are not at the beginning or end of the some line strip
|
||||
UINT i1=y1*(m_iColSec+1)+x1;
|
||||
UINT i2=y2*(m_iColSec+1)+x2;
|
||||
|
||||
cline_strip* pStrip;
|
||||
|
||||
cline_strip_list::iterator pos;
|
||||
bool added = false;
|
||||
for(pos=m_vStripLists[iPlane].begin(); pos!=m_vStripLists[iPlane].end() && !added; pos++)
|
||||
{
|
||||
pStrip=(*pos);
|
||||
_ASSERTP_(pStrip,"clist_contour::ExportLine::2");
|
||||
// check if points are appendable to this strip
|
||||
if (i1==pStrip->front())
|
||||
{
|
||||
pStrip->insert(pStrip->begin(),i2);
|
||||
return;
|
||||
}
|
||||
if (i1==pStrip->back())
|
||||
{
|
||||
pStrip->insert(pStrip->end(),i2);
|
||||
return;
|
||||
}
|
||||
if (i2==pStrip->front())
|
||||
{
|
||||
pStrip->insert(pStrip->begin(),i1);
|
||||
return;
|
||||
}
|
||||
if (i2==pStrip->back())
|
||||
{
|
||||
pStrip->insert(pStrip->end(),i1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// segment was not part of any line strip, creating new one
|
||||
pStrip=new cline_strip;
|
||||
pStrip->insert(pStrip->begin(),i1);
|
||||
pStrip->insert(pStrip->end(),i2);
|
||||
m_vStripLists[iPlane].insert(m_vStripLists[iPlane].begin(),pStrip);
|
||||
}
|
||||
|
||||
inline bool clist_contour::ForceMerge(cline_strip* pStrip1, cline_strip* pStrip2,double aHeight)
|
||||
{
|
||||
|
||||
cline_strip::iterator pos;
|
||||
cline_strip::reverse_iterator rpos;
|
||||
|
||||
if (pStrip2->empty())
|
||||
return false;
|
||||
|
||||
double x[4], y[4], weldDist;
|
||||
int index;
|
||||
index = pStrip1->front();
|
||||
x[0] = get_xi(index);
|
||||
y[0] = get_yi(index);
|
||||
index = pStrip1->back();
|
||||
x[1] = get_xi(index);
|
||||
y[1] = get_yi(index);
|
||||
index = pStrip2->front();
|
||||
x[2] = get_xi(index);
|
||||
y[2] = get_yi(index);
|
||||
index = pStrip2->back();
|
||||
x[3] = get_xi(index);
|
||||
y[3] = get_yi(index);
|
||||
|
||||
weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);
|
||||
|
||||
if (((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2])< weldDist)
|
||||
|| SpecialCompactStripCase(x[1],x[2],y[1],y[2],aHeight)) // L.Garnier
|
||||
|
||||
{
|
||||
for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
|
||||
{
|
||||
index=(*pos);
|
||||
if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::0")) return false;
|
||||
pStrip1->insert(pStrip1->end(),index);
|
||||
}
|
||||
pStrip2->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((x[3]-x[0])*(x[3]-x[0])+(y[3]-y[0])*(y[3]-y[0])< weldDist)
|
||||
|| SpecialCompactStripCase(x[3],x[0],y[3],y[0],aHeight)) // L.Garnier
|
||||
{
|
||||
for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
|
||||
{
|
||||
index=(*rpos);
|
||||
if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::1")) return false;
|
||||
pStrip1->insert(pStrip1->begin(),index);
|
||||
}
|
||||
pStrip2->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3])< weldDist)
|
||||
|| SpecialCompactStripCase(x[1],x[3],y[1],y[3],aHeight)) // L.Garnier
|
||||
{
|
||||
for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
|
||||
{
|
||||
index=(*rpos);
|
||||
if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::2")) return false;
|
||||
pStrip1->insert(pStrip1->end(),index);
|
||||
}
|
||||
pStrip2->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((x[0]-x[2])*(x[0]-x[2])+(y[0]-y[2])*(y[0]-y[2])< weldDist)
|
||||
|| SpecialCompactStripCase(x[0],x[2],y[0],y[2],aHeight)) // L.Garnier
|
||||
{
|
||||
for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
|
||||
{
|
||||
index=(*pos);
|
||||
if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::3")) return false;
|
||||
pStrip1->insert(pStrip1->begin(),index);
|
||||
}
|
||||
pStrip2->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool clist_contour::MergeStrips(cline_strip* pStrip1, cline_strip* pStrip2)
|
||||
{
|
||||
cline_strip::iterator pos;
|
||||
cline_strip::reverse_iterator rpos;
|
||||
if (pStrip2->empty())
|
||||
return false;
|
||||
|
||||
int index;
|
||||
|
||||
// debugging stuff
|
||||
if (pStrip2->front()==pStrip1->front())
|
||||
{
|
||||
// retreiving first element
|
||||
pStrip2->pop_front();
|
||||
// adding the rest to strip1
|
||||
for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
|
||||
{
|
||||
index=(*pos);
|
||||
if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::0",pStrip2)) return false;
|
||||
pStrip1->insert(pStrip1->begin(),index);
|
||||
}
|
||||
pStrip2->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pStrip2->front()==pStrip1->back())
|
||||
{
|
||||
pStrip2->pop_front();
|
||||
// adding the rest to strip1
|
||||
for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
|
||||
{
|
||||
index=(*pos);
|
||||
if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::1",pStrip2)) return false;
|
||||
pStrip1->insert(pStrip1->end(),index);
|
||||
}
|
||||
pStrip2->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pStrip2->back()==pStrip1->front())
|
||||
{
|
||||
pStrip2->pop_back();
|
||||
// adding the rest to strip1
|
||||
for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
|
||||
{
|
||||
index=(*rpos);
|
||||
if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::2",pStrip2)) return false;
|
||||
pStrip1->insert(pStrip1->begin(),index);
|
||||
}
|
||||
pStrip2->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pStrip2->back()==pStrip1->back())
|
||||
{
|
||||
pStrip2->pop_back();
|
||||
// adding the rest to strip1
|
||||
for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
|
||||
{
|
||||
index=(*rpos);
|
||||
if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::3",pStrip2)) return false;
|
||||
pStrip1->insert(pStrip1->end(),index);
|
||||
}
|
||||
pStrip2->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool clist_contour::compact_strips ()
|
||||
{
|
||||
cline_strip* pStrip;
|
||||
cline_strip* pStripBase = 0;
|
||||
UINT i;
|
||||
cline_strip_list::iterator pos,pos2;
|
||||
cline_strip_list newList;
|
||||
bool again, changed;
|
||||
|
||||
const double weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);
|
||||
|
||||
if(!_ASSERT_RET_(m_vStripLists.size() == get_number_of_planes(),"clist_contour::compact_strips ::0")) return false;
|
||||
for (i=0;i<get_number_of_planes();i++)
|
||||
{
|
||||
double planeHeight = get_plane(i);
|
||||
again=true;
|
||||
while(again)
|
||||
{
|
||||
// REPEAT COMPACT PROCESS UNTILL LAST PROCESS MAKES NO CHANGE
|
||||
|
||||
again=false;
|
||||
// building compacted list
|
||||
if(!_ASSERT_RET_(newList.empty(),"clist_contour::compact_strips ::1")) return false;
|
||||
for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++)
|
||||
{
|
||||
pStrip=(*pos);
|
||||
for (pos2=newList.begin(); pos2!=newList.end();pos2++)
|
||||
{
|
||||
pStripBase=(*pos2);
|
||||
changed=MergeStrips(pStripBase,pStrip);
|
||||
if (changed)
|
||||
again=true;
|
||||
if (pStrip->empty())
|
||||
break;
|
||||
}
|
||||
if (pStrip->empty())
|
||||
delete pStrip;
|
||||
else
|
||||
newList.insert(newList.begin(),pStrip);
|
||||
}
|
||||
|
||||
|
||||
// deleting old list
|
||||
m_vStripLists[i].clear();
|
||||
cline_strip* pStrip2;
|
||||
// Copying all
|
||||
for (pos2=newList.begin(); pos2 != newList.end(); pos2++)
|
||||
{
|
||||
pStrip2=(*pos2);
|
||||
cline_strip::iterator pos1 = pStrip2->begin(),pos3;
|
||||
while (pos1!=pStrip2->end())
|
||||
{
|
||||
pos3 = pos1;
|
||||
pos3++;
|
||||
if (pos3==pStrip2->end()) break; //G.Barrand
|
||||
if ( (*pos1) == (*pos3))
|
||||
{
|
||||
/*G.Barrand : we can't compare with pStrip2->end() content.
|
||||
if ( (*pos3) != (*pStrip2->end()))
|
||||
pStrip2->erase(pos3);
|
||||
else
|
||||
{
|
||||
pStrip2->erase(pos3);
|
||||
break;
|
||||
}
|
||||
*/
|
||||
pStrip2->erase(pos3); //G.Barrand.
|
||||
}
|
||||
else
|
||||
pos1++;
|
||||
}
|
||||
|
||||
//if (!(pStrip2->front()==pStrip2->back() && pStrip2->size()==2))
|
||||
if (pStrip2->size()!=1)
|
||||
m_vStripLists[i].insert(m_vStripLists[i].begin(),pStrip2 );
|
||||
else
|
||||
delete pStrip2;
|
||||
}
|
||||
// emptying temp list
|
||||
newList.clear();
|
||||
|
||||
} // OF WHILE(AGAIN) (LAST COMPACT PROCESS MADE NO CHANGES)
|
||||
|
||||
|
||||
if (m_vStripLists[i].empty())
|
||||
continue;
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// compact more
|
||||
int index,count;
|
||||
size_t Nstrip,j;
|
||||
|
||||
Nstrip = m_vStripLists[i].size();
|
||||
std::vector<bool> closed(Nstrip);
|
||||
double x,y;
|
||||
|
||||
// First let's find the open and closed lists in m_vStripLists
|
||||
for(pos2 = m_vStripLists[i].begin(), j=0, count=0; pos2 != m_vStripLists[i].end(); pos2++, j++)
|
||||
{
|
||||
pStrip = (*pos2);
|
||||
|
||||
// is it open ?
|
||||
if (pStrip->front() != pStrip->back())
|
||||
{
|
||||
index = pStrip->front();
|
||||
x = get_xi(index); y = get_yi(index);
|
||||
index = pStrip->back();
|
||||
x -= get_xi(index); y -= get_yi(index);
|
||||
|
||||
// is it "almost closed" ?
|
||||
if ((x*x+y*y < weldDist) ||
|
||||
SpecialCompactStripCase(get_xi(pStrip->front()), // L.Garnier
|
||||
get_xi(pStrip->back()),
|
||||
get_yi(pStrip->front()),
|
||||
get_yi(pStrip->back()),
|
||||
planeHeight))
|
||||
{
|
||||
closed[j] = true;
|
||||
// close it !!! Added by L.Garnier
|
||||
pStrip->push_back(pStrip->front());
|
||||
//
|
||||
}
|
||||
else
|
||||
{
|
||||
closed[j] = false;
|
||||
// updating not closed counter...
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
else
|
||||
closed[j] = true;
|
||||
}
|
||||
|
||||
// is there any open strip ?
|
||||
if (count > 1)
|
||||
{
|
||||
// Merge the open strips into NewList
|
||||
pos = m_vStripLists[i].begin();
|
||||
for(j=0;j<Nstrip;j++)
|
||||
{
|
||||
if (closed[j] == false )
|
||||
{
|
||||
pStrip = (*pos);
|
||||
newList.insert(newList.begin(),pStrip);
|
||||
pos = m_vStripLists[i].erase(pos);
|
||||
}
|
||||
else
|
||||
pos ++;
|
||||
}
|
||||
|
||||
// are they open strips to process ?
|
||||
while(newList.size()>1)
|
||||
{
|
||||
pStripBase = newList.front();
|
||||
|
||||
// merge the rest to pStripBase
|
||||
again = true;
|
||||
while (again)
|
||||
{
|
||||
again = false;
|
||||
pos = newList.begin();
|
||||
for(pos++; pos!=newList.end();)
|
||||
{
|
||||
pStrip = (*pos);
|
||||
changed = ForceMerge(pStripBase,pStrip,planeHeight);
|
||||
if (changed)
|
||||
{
|
||||
again = true;
|
||||
delete pStrip;
|
||||
pos = newList.erase(pos);
|
||||
}
|
||||
else
|
||||
pos ++;
|
||||
}
|
||||
} // while(again)
|
||||
|
||||
index = pStripBase->front();
|
||||
x = get_xi(index); y = get_yi(index);
|
||||
index = pStripBase->back();
|
||||
x -= get_xi(index); y -= get_yi(index);
|
||||
// if pStripBase is closed or not
|
||||
|
||||
if ((x*x+y*y < weldDist) ||
|
||||
SpecialCompactStripCase(get_xi(pStripBase->front()), // L.Garnier
|
||||
get_xi(pStripBase->back()),
|
||||
get_yi(pStripBase->front()),
|
||||
get_yi(pStripBase->back()),
|
||||
planeHeight))
|
||||
{
|
||||
|
||||
// close it !!! Added by L.Garnier
|
||||
if ((x!=0) || (y!=0)) {
|
||||
pStripBase->push_back(pStripBase->front());
|
||||
}
|
||||
//
|
||||
m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
|
||||
newList.pop_front();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OnBoundary(pStripBase))
|
||||
{
|
||||
_TRACE_(_TT("# open strip ends on boundary, continue.\n"));
|
||||
m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
|
||||
newList.pop_front();
|
||||
}
|
||||
else
|
||||
{
|
||||
_PROBLEM_(_TT("unpaird open strip at 1!\n"));
|
||||
//exit(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // while(newList.size()>1);
|
||||
|
||||
|
||||
if (newList.size() ==1)
|
||||
{
|
||||
pStripBase = newList.front();
|
||||
index = pStripBase->front(); // L.Garnier
|
||||
x = get_xi(index); y = get_yi(index); // L.Garnier
|
||||
index = pStripBase->back(); // L.Garnier
|
||||
x -= get_xi(index); y -= get_yi(index); // L.Garnier
|
||||
|
||||
// is it "almost closed", give last chance...5*weldDist
|
||||
if (x*x+y*y < 3*weldDist) // L.Garnier
|
||||
{
|
||||
m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
|
||||
newList.pop_front();
|
||||
}
|
||||
else if (OnBoundary(pStripBase))
|
||||
{
|
||||
_TRACE_(_TT("# open strip ends on boundary, continue.\n"));
|
||||
m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
|
||||
newList.pop_front();
|
||||
}
|
||||
else
|
||||
{
|
||||
_PROBLEM_(_TT("unpaird open strip at 2!\n"));
|
||||
DumpPlane(i);
|
||||
//exit(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
newList.clear();
|
||||
|
||||
}
|
||||
else if (count == 1)
|
||||
{
|
||||
pos = m_vStripLists[i].begin();
|
||||
for(j=0;j<Nstrip;j++)
|
||||
{
|
||||
if (closed[j] == false )
|
||||
{
|
||||
pStripBase = (*pos);
|
||||
break;
|
||||
}
|
||||
pos ++;
|
||||
}
|
||||
index = pStripBase->front(); // L.Garnier
|
||||
x = get_xi(index); y = get_yi(index); // L.Garnier
|
||||
index = pStripBase->back(); // L.Garnier
|
||||
x -= get_xi(index); y -= get_yi(index); // L.Garnier
|
||||
|
||||
// is it "almost closed", give last chance...5*weldDist
|
||||
if (x*x+y*y < 2*weldDist) // L.Garnier
|
||||
{
|
||||
//close it!!
|
||||
pStripBase->push_back(pStripBase->front()); // L.Garnier
|
||||
}
|
||||
else if (OnBoundary(pStripBase))
|
||||
{
|
||||
_TRACE_(_TT("# open strip ends on boundary, continue.\n"));
|
||||
pStripBase->push_back(pStripBase->front()); // L.Garnier
|
||||
}
|
||||
else
|
||||
{
|
||||
_TRACE_(_TT("unpaird open strip at 3!"));
|
||||
DumpPlane(i);
|
||||
return false; // L.Garnier
|
||||
//exit(0);
|
||||
}
|
||||
newList.clear(); // L.Garnier
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool clist_contour::OnBoundary(cline_strip* pStrip)
|
||||
{
|
||||
bool e1,e2;
|
||||
|
||||
int index = pStrip->front();
|
||||
double x = get_xi(index), y = get_yi(index);
|
||||
if (x==m_pLimits[0] || x == m_pLimits[1] ||
|
||||
y == m_pLimits[2] || y == m_pLimits[3])
|
||||
e1 = true;
|
||||
else
|
||||
e1 = false;
|
||||
|
||||
index = pStrip->back();
|
||||
x = get_xi(index); y = get_yi(index);
|
||||
if (x==m_pLimits[0] || x == m_pLimits[1] ||
|
||||
y == m_pLimits[2] || y == m_pLimits[3])
|
||||
e2 = true;
|
||||
else
|
||||
e2 = false;
|
||||
|
||||
return (e1 && e2);
|
||||
}
|
||||
|
||||
inline void clist_contour::DumpPlane(UINT iPlane) const
|
||||
{
|
||||
cline_strip_list::const_iterator pos;
|
||||
UINT i;
|
||||
cline_strip* pStrip;
|
||||
|
||||
/*_ASSERT_(iPlane>=0,"clist_contour::DumpPlane");*/
|
||||
_ASSERT_(iPlane<get_number_of_planes(),"clist_contour::DumpPlane::0");
|
||||
_TRACE_(_TT("Level : %d"),get_plane(iPlane));
|
||||
|
||||
_TRACE_(_TT("Number of strips : %d\r\n"),m_vStripLists[iPlane].size());
|
||||
_TRACE_(_TT("i np start end xstart ystart xend yend\r\n"));
|
||||
for (pos = m_vStripLists[iPlane].begin(), i=0; pos != m_vStripLists[iPlane].end(); pos++, i++)
|
||||
{
|
||||
pStrip=*pos;
|
||||
_ASSERTP_(pStrip,"clist_contour::DumpPlane::1");
|
||||
_TRACE_(_TT("%d %d %d %d %g %g %g %g\r\n"),i,pStrip->size(),pStrip->front(),pStrip->back(),
|
||||
get_xi(pStrip->front()),get_yi(pStrip->front()),
|
||||
get_xi(pStrip->back()),get_yi(pStrip->back()) );
|
||||
}
|
||||
}
|
||||
|
||||
inline double clist_contour::Area(cline_strip* Line)
|
||||
{
|
||||
// if Line is not closed, return 0;
|
||||
|
||||
double Ar = 0, x, y, x0,y0,x1, y1;
|
||||
int index;
|
||||
|
||||
cline_strip::iterator pos;
|
||||
pos = Line->begin();
|
||||
index = (*pos);
|
||||
x0 = x = get_xi(index);
|
||||
y0 = y = get_yi(index);
|
||||
|
||||
pos ++;
|
||||
|
||||
for(;pos!=Line->end();pos++)
|
||||
{
|
||||
index = (*pos);
|
||||
x1 = get_xi(index);
|
||||
y1 = get_yi(index);
|
||||
// Ar += (x1-x)*(y1+y);
|
||||
Ar += (y1-y)*(x1+x)-(x1-x)*(y1+y);
|
||||
x = x1;
|
||||
y = y1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Ar += (x0-x)*(y0+y);
|
||||
Ar += (y0-y)*(x0+x)-(x0-x)*(y0+y);
|
||||
// if not closed curve, return 0;
|
||||
if ((x0-x)*(x0-x) + (y0-y)*(y0-y)>20*(m_dDx*m_dDx+m_dDy*m_dDy))
|
||||
{
|
||||
Ar = 0;
|
||||
_TRACE_(_TT("# open curve!\n"));
|
||||
}
|
||||
//else Ar /= -2;
|
||||
else Ar/=4;
|
||||
// result is \int ydex/2 alone the implicit direction.
|
||||
return Ar;
|
||||
}
|
||||
|
||||
inline double clist_contour:: EdgeWeight(cline_strip* pLine, double R)
|
||||
{
|
||||
cline_strip::iterator pos;
|
||||
int count = 0,index;
|
||||
double x,y;
|
||||
for(pos = pLine->begin(); pos!=pLine->end(); pos++)
|
||||
{
|
||||
index = (*pos);
|
||||
x = get_xi(index);
|
||||
y = get_yi(index);
|
||||
if (fabs(x) > R || fabs(y) > R)
|
||||
count ++;
|
||||
}
|
||||
return (double)count/pLine->size();
|
||||
}
|
||||
|
||||
/*
|
||||
inline bool clist_contour::PrintContour(std::ostream& a_out)
|
||||
{
|
||||
std::streamsize old_prec = a_out.precision(3);
|
||||
a_out << std::setprecision(10);
|
||||
|
||||
UINT i, index;
|
||||
cline_strip* pStrip;
|
||||
cline_strip::iterator pos2;
|
||||
cline_strip_list::iterator pos;
|
||||
|
||||
for(i=0;i<get_number_of_planes();i++) {
|
||||
for(pos = m_vStripLists[i].begin();pos!=m_vStripLists[i].end();pos++)
|
||||
{
|
||||
pStrip = (*pos);
|
||||
for(pos2 = pStrip->begin();pos2!=pStrip->end();pos2++)
|
||||
{
|
||||
index = (*pos2);
|
||||
a_out << get_xi(index)<<"\t"<<get_yi(index)<<"\n";
|
||||
}
|
||||
a_out<<"\n";
|
||||
}
|
||||
}
|
||||
a_out.precision(old_prec);
|
||||
return true;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
//G.Barrand : from .h to .cxx to avoid _ASSERT_ in .h
|
||||
inline cline_strip_list* clist_contour::get_lines(unsigned int iPlane) {
|
||||
/*_ASSERT_(iPlane>=0);*/
|
||||
_ASSERT_(iPlane<get_number_of_planes(),"clist_contour::get_lines");
|
||||
return &m_vStripLists[iPlane];
|
||||
}
|
||||
|
||||
// Added by L.Garnier
|
||||
inline bool clist_contour::SpecialCompactStripCase(double aXfront,double aXback,double aYfront,double aYback,double actualHeight)
|
||||
{
|
||||
// To solve the case of a list of strips
|
||||
// which appeared to be open but should correspond to a closed
|
||||
// contour.
|
||||
// With the today generate() algorithm, it appears that we fall
|
||||
// on this case when the begin and end points
|
||||
// are on a horizontal or vertical line.
|
||||
// (case where front()->x == back()->x or front()->y == back()->y).
|
||||
// We try to detect in this method this situation and decide to close
|
||||
// or not the line. To do that we check the heigth of intermediate
|
||||
// points to see if there are on the same contour; if so we close
|
||||
// the line (and return true), if not we do nothing (and return false).
|
||||
|
||||
// check if we could realy close it
|
||||
float marge = 1; // *m_dDy or *m_dDx. 1 seems to be good and normal, but why
|
||||
// not 2 in certain cases???
|
||||
|
||||
double distToNext =0;
|
||||
// try to get the correct hight
|
||||
if (get_plane(0)>= actualHeight) {
|
||||
return false;
|
||||
}
|
||||
if (get_number_of_planes() >1){
|
||||
distToNext = get_plane(1)-get_plane(0);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((aYback-aYfront) == 0) {
|
||||
double temp;
|
||||
double av;
|
||||
double eg;
|
||||
double ap;
|
||||
|
||||
if (aXfront==m_pLimits[0] && aXback == m_pLimits[1]) return false;
|
||||
if (aXfront==m_pLimits[1] && aXback == m_pLimits[0]) return false;
|
||||
|
||||
if (aXfront > aXback ) {
|
||||
temp = aXfront;
|
||||
aXfront = aXback;
|
||||
aXback = temp;
|
||||
}
|
||||
for(double check=aXfront+m_dDx;
|
||||
check<aXback;
|
||||
check+=m_dDx) {
|
||||
av = ((*m_pFieldFcn)(check,aYback-marge*m_dDy,m_pFieldFcnData)-actualHeight);
|
||||
eg = ((*m_pFieldFcn)(check,aYback,m_pFieldFcnData)-actualHeight);
|
||||
ap = ((*m_pFieldFcn)(check,aYback+marge*m_dDy,m_pFieldFcnData)-actualHeight);
|
||||
|
||||
if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) {
|
||||
return false;
|
||||
} else if ((av<0) && (ap<0) && (eg<0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if ((aXback-aXfront) == 0) {
|
||||
double temp;
|
||||
double av;
|
||||
double eg;
|
||||
double ap;
|
||||
if (aYfront==m_pLimits[3] && aYback == m_pLimits[2]) return false;
|
||||
if (aYfront==m_pLimits[2] && aYback == m_pLimits[3]) return false;
|
||||
|
||||
if (aYfront > aYback ) {
|
||||
temp = aYfront;
|
||||
aYfront = aYback;
|
||||
aYback = temp;
|
||||
}
|
||||
|
||||
for(double check=aYfront+m_dDy;
|
||||
check<aYback;
|
||||
check+=m_dDy) {
|
||||
av = ((*m_pFieldFcn)(aXback-marge*m_dDx,check,m_pFieldFcnData)-actualHeight);
|
||||
eg = ((*m_pFieldFcn)(aXback,check,m_pFieldFcnData)-actualHeight);
|
||||
ap = ((*m_pFieldFcn)(aXback+marge*m_dDx,check,m_pFieldFcnData)-actualHeight);
|
||||
if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) {
|
||||
return false;
|
||||
} else if ((av<0) && (ap<0) && (eg<0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,11 @@ public:
|
||||
TOOLS_SCLASS(tools::colorf) //for stype()
|
||||
public:
|
||||
colorf():parent(0,0,0,1){}
|
||||
#ifdef TOOLS_MEM
|
||||
colorf(float a_r,float a_g,float a_b,float a_a = 1,bool a_inc = true):parent(a_r,a_g,a_b,a_a,a_inc){}
|
||||
#else
|
||||
colorf(float a_r,float a_g,float a_b,float a_a = 1):parent(a_r,a_g,a_b,a_a){}
|
||||
#endif
|
||||
virtual ~colorf() {}
|
||||
public:
|
||||
colorf(const colorf& a_from):parent(a_from){}
|
||||
@@ -35,15 +39,23 @@ public:
|
||||
void set_b(float a_v) {m_data[2] = a_v;}
|
||||
void set_a(float a_v) {m_data[3] = a_v;}
|
||||
|
||||
uchar ruchar() const {return uchar(255.0f*m_data[0]);}
|
||||
uchar guchar() const {return uchar(255.0f*m_data[1]);}
|
||||
uchar buchar() const {return uchar(255.0f*m_data[2]);}
|
||||
uchar auchar() const {return uchar(255.0f*m_data[3]);}
|
||||
|
||||
#ifdef tools_colorf
|
||||
// deprecated, use the upper ones.
|
||||
uchar rchar() const {return uchar(255.0f*m_data[0]);}
|
||||
uchar gchar() const {return uchar(255.0f*m_data[1]);}
|
||||
uchar bchar() const {return uchar(255.0f*m_data[2]);}
|
||||
#endif
|
||||
|
||||
public:
|
||||
//#define tools_stat_colorfs
|
||||
#ifdef tools_stat_colorfs
|
||||
//NOTE : the below are deprecated, use functions in inlib/colorfs.
|
||||
// tools::colorf::white() replaced by tools::colorf_white()
|
||||
// colorf::white() replaced by colorf_white()
|
||||
|
||||
// our forever 65 named colors taken long time ago from X11.
|
||||
|
||||
@@ -143,6 +155,12 @@ struct cmp_colorf {
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
inline const colorf& colorf_default() {static const colorf s_v(0.8f,0.8f,0.8f,1,false);return s_v;}
|
||||
#else
|
||||
inline const colorf& colorf_default() {static const colorf s_v(0.8f,0.8f,0.8f,1);return s_v;}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -93,11 +93,15 @@ TOOLS_COLORS_SET(greenyellow,0.675792F,0.996109F,0.18359F)
|
||||
|
||||
#undef TOOLS_COLORS_SET
|
||||
|
||||
#if defined(TOOLS_MEM) && !defined(TOOLS_MEM_ATEXIT)
|
||||
#define TOOLS_COLORS_STAT(a__name,a__r,a__g,a__b) \
|
||||
template <class COLOR>\
|
||||
inline const COLOR& get_color_##a__name() {static const COLOR s_v(a__r,a__g,a__b,1,false);return s_v;}
|
||||
|
||||
//NOTE : false in the upper so that mem balance is ok at exit.
|
||||
#else
|
||||
#define TOOLS_COLORS_STAT(a__name,a__r,a__g,a__b) \
|
||||
template <class COLOR>\
|
||||
inline const COLOR& get_color_##a__name() {static const COLOR s_v(a__r,a__g,a__b,1);return s_v;}
|
||||
#endif
|
||||
|
||||
//0-9
|
||||
TOOLS_COLORS_STAT(aquamarine,0.496101F,0.996109F,0.828138F)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "forit"
|
||||
#include "sout"
|
||||
#include "schar"
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
#include "mem"
|
||||
@@ -159,8 +160,7 @@ inline void delete_columns(std::vector<value>& a_vars) {
|
||||
a_vars.clear();
|
||||
}
|
||||
|
||||
inline void copy_columns(const std::vector<value>& a_from,
|
||||
std::vector<value>& a_to) {
|
||||
inline void copy_columns(const std::vector<value>& a_from,std::vector<value>& a_to) {
|
||||
std::vector<value>::const_iterator it;
|
||||
for(it=a_from.begin();it!=a_from.end();++it) {
|
||||
if((*it).type()==value::VOID_STAR) {
|
||||
@@ -177,9 +177,7 @@ inline void copy_columns(const std::vector<value>& a_from,
|
||||
}
|
||||
}
|
||||
|
||||
inline void dump_columns(std::ostream& a_out,
|
||||
const std::vector<value>& a_vars,
|
||||
const std::string& a_margin = "") {
|
||||
inline void dump_columns(std::ostream& a_out,const std::vector<value>& a_vars,const std::string& a_margin = "") {
|
||||
std::vector<value>::const_iterator it;
|
||||
for(it=a_vars.begin();it!=a_vars.end();++it) {
|
||||
if((*it).type()==value::VOID_STAR) {
|
||||
@@ -192,7 +190,6 @@ inline void dump_columns(std::ostream& a_out,
|
||||
// << "ITuple : " << (*it).label() << " : end "
|
||||
// << std::endl;
|
||||
} else {
|
||||
//(*it).print(a_out);
|
||||
std::string stype;
|
||||
(*it).s_type(stype);
|
||||
std::string sval;
|
||||
@@ -207,7 +204,7 @@ inline void dump_columns(std::ostream& a_out,
|
||||
}
|
||||
}
|
||||
|
||||
class finder : public tools::columns::parser {
|
||||
class finder : public columns::parser {
|
||||
public:
|
||||
finder(std::ostream& a_out,const std::string& a_script)
|
||||
:m_out(a_out)
|
||||
@@ -231,10 +228,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<value> result() const {
|
||||
std::vector<value> vars;
|
||||
copy_columns(m_stack,vars);
|
||||
return vars;
|
||||
void result(std::vector<value>& a_vars) const {
|
||||
a_vars.clear();
|
||||
copy_columns(m_stack,a_vars);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
@@ -248,15 +244,15 @@ public:
|
||||
std::ostream& out() const {return m_out;}
|
||||
*/
|
||||
protected:
|
||||
bool analyse(tools::columns::tree& a_tree,
|
||||
std::vector<value>& a_stack) {
|
||||
bool analyse(columns::tree& a_tree,std::vector<value>& a_stack) {
|
||||
if(a_tree.m_dcl.empty()) { //top
|
||||
//std::cout << "debug : dcl empty" << std::endl;
|
||||
tools_vforit(tools::columns::tree,a_tree.m_sub,it) {
|
||||
tools_vforit(columns::tree,a_tree.m_sub,it) {
|
||||
if(!analyse(*it,a_stack)) return false;
|
||||
}
|
||||
} else {
|
||||
//std::cout << "debug : dcl not empty" << std::endl;
|
||||
if(is_spaces(a_tree.m_dcl)) return true;
|
||||
value* v = analyse_dcl(a_tree.m_dcl);
|
||||
if(!v) return false;
|
||||
//std::cout << "debug : dcl label " << v->label() << std::endl;
|
||||
@@ -270,7 +266,7 @@ protected:
|
||||
}
|
||||
m_cur_type = value::NONE;
|
||||
std::vector<value>* stk = new std::vector<value>();
|
||||
tools_vforit(tools::columns::tree,a_tree.m_sub,it) {
|
||||
tools_vforit(columns::tree,a_tree.m_sub,it) {
|
||||
if(!analyse(*it,*stk)) {
|
||||
delete v;
|
||||
return false;
|
||||
@@ -286,15 +282,15 @@ protected:
|
||||
return true;
|
||||
}
|
||||
value* analyse_dcl(const std::string& a_s) {
|
||||
std::vector<std::string> words;
|
||||
tools::words(a_s,"=",false,words);
|
||||
if(words.size()==2) { //<type> <name>=<value>
|
||||
std::vector<std::string> ws;
|
||||
words(a_s,"=",false,ws);
|
||||
if(ws.size()==2) { //<type> <name>=<value>
|
||||
std::vector<std::string> swords;
|
||||
tools::words(words[0]," ",false,swords);
|
||||
words(ws[0]," ",false,swords);
|
||||
if(swords.size()==2) {
|
||||
|
||||
tools::strip(swords[0]);
|
||||
tools::strip(swords[1]);
|
||||
strip(swords[0]);
|
||||
strip(swords[1]);
|
||||
|
||||
if(swords[0]=="ITuple") {
|
||||
|
||||
@@ -308,16 +304,16 @@ protected:
|
||||
value::e_type type;
|
||||
if(!s2type(swords[0],type)){
|
||||
m_out << "tools::columns::finder::analyse_dcl :"
|
||||
<< " s2type failed for " << tools::sout(swords[0]) << "."
|
||||
<< " s2type failed for " << sout(swords[0]) << "."
|
||||
<< std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tools::strip(words[1]);
|
||||
value* v = new_value(type,words[1]);
|
||||
strip(ws[1]);
|
||||
value* v = new_value(type,ws[1]);
|
||||
if(!v) {
|
||||
m_out << "tools::columns::finder::analyse_dcl :"
|
||||
<< " syntax error in " << tools::sout(a_s) << "."
|
||||
<< " syntax error in " << sout(a_s) << "."
|
||||
<< " new_value() failed."
|
||||
<< std::endl;
|
||||
return 0;
|
||||
@@ -335,12 +331,12 @@ protected:
|
||||
return 0;
|
||||
}
|
||||
|
||||
tools::strip(words[1]);
|
||||
value* v = new_value(m_cur_type,words[1]);
|
||||
strip(ws[1]);
|
||||
value* v = new_value(m_cur_type,ws[1]);
|
||||
if(!v) {
|
||||
m_out << "tools::columns::finder::analyse_dcl :"
|
||||
<< " syntax error in " << tools::sout(a_s) << "."
|
||||
<< " Bad value " << tools::sout(words[1]) << "."
|
||||
<< " syntax error in " << sout(a_s) << "."
|
||||
<< " Bad value " << sout(ws[1]) << "."
|
||||
<< std::endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -349,20 +345,20 @@ protected:
|
||||
|
||||
} else {
|
||||
m_out << "tools::columns::finder::analyse_dcl :"
|
||||
<< " syntax error in " << tools::sout(a_s)
|
||||
<< " syntax error in " << sout(a_s)
|
||||
<< ". Case 1."
|
||||
<< std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else if(words.size()==1) {
|
||||
} else if(ws.size()==1) {
|
||||
//<type> <name>
|
||||
//<type> <name>={
|
||||
std::vector<std::string> swords;
|
||||
tools::words(words[0]," ",false,swords);
|
||||
words(ws[0]," ",false,swords);
|
||||
if(swords.size()==2) {
|
||||
tools::strip(swords[0]);
|
||||
tools::strip(swords[1]);
|
||||
strip(swords[0]);
|
||||
strip(swords[1]);
|
||||
|
||||
if(swords[0]=="ITuple") {
|
||||
|
||||
@@ -375,7 +371,7 @@ protected:
|
||||
value::e_type type;
|
||||
if(!s2type(swords[0],type)){
|
||||
m_out << "tools::columns::finder::analyse_dcl :"
|
||||
<< " s2type failed for " << tools::sout(swords[0]) << "."
|
||||
<< " s2type failed for " << sout(swords[0]) << "."
|
||||
<< std::endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -383,8 +379,8 @@ protected:
|
||||
value* v = new_value(type,"");
|
||||
if(!v) {
|
||||
m_out << "tools::columns::finder::analyse_dcl :"
|
||||
<< " (2) syntax error in " << tools::sout(words[0]) << "."
|
||||
<< " Unknown type " << tools::sout(swords[0]) << "."
|
||||
<< " (2) syntax error in " << sout(ws[0]) << "."
|
||||
<< " Unknown type " << sout(swords[0]) << "."
|
||||
<< std::endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -408,7 +404,7 @@ protected:
|
||||
|
||||
} else {
|
||||
m_out << "tools::columns::finder::analyse_dcl :"
|
||||
<< " syntax error in " << tools::sout(a_s)
|
||||
<< " syntax error in " << sout(a_s)
|
||||
<< ". Case 2."
|
||||
<< std::endl;
|
||||
return 0;
|
||||
@@ -416,7 +412,7 @@ protected:
|
||||
|
||||
} else {
|
||||
m_out << "tools::columns::finder::analyse_dcl :"
|
||||
<< " syntax error in " << tools::sout(a_s)
|
||||
<< " syntax error in " << sout(a_s)
|
||||
<< ". Case 3."
|
||||
<< std::endl;
|
||||
return 0;
|
||||
@@ -476,36 +472,35 @@ protected:
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static value* new_value(value::e_type a_type,
|
||||
const std::string& a_v) {
|
||||
static value* new_value(value::e_type a_type,const std::string& a_v) {
|
||||
if(a_type==value::FLOAT) {
|
||||
float v = 0;
|
||||
if(a_v.size()) {if(!tools::to<float>(a_v,v)) return 0;}
|
||||
if(a_v.size()) {if(!to<float>(a_v,v)) return 0;}
|
||||
return new value(v);
|
||||
} else if(a_type==value::DOUBLE) {
|
||||
double v = 0;
|
||||
if(a_v.size()) {if(!tools::to<double>(a_v,v)) return 0;}
|
||||
if(a_v.size()) {if(!to<double>(a_v,v)) return 0;}
|
||||
return new value(v);
|
||||
//} else if(a_type==value::CHAR) {
|
||||
// char v = 0;
|
||||
// if(a_v.size()) {if(!tools::to<char>(a_v,v)) return 0;}
|
||||
// if(a_v.size()) {if(!to<char>(a_v,v)) return 0;}
|
||||
// return new value(v);
|
||||
} else if(a_type==value::SHORT) {
|
||||
short v = 0;
|
||||
if(a_v.size()) {if(!tools::to<short>(a_v,v)) return 0;}
|
||||
if(a_v.size()) {if(!to<short>(a_v,v)) return 0;}
|
||||
return new value(v);
|
||||
} else if(a_type==value::INT) {
|
||||
int v = 0;
|
||||
if(a_v.size()) {if(!tools::to<int>(a_v,v)) return 0;}
|
||||
if(a_v.size()) {if(!to<int>(a_v,v)) return 0;}
|
||||
return new value(v);
|
||||
|
||||
} else if(a_type==value::INT64) {
|
||||
int64 v = 0;
|
||||
if(a_v.size()) {if(!tools::to<int64>(a_v,v)) return 0;}
|
||||
if(a_v.size()) {if(!to<int64>(a_v,v)) return 0;}
|
||||
return new value(v);
|
||||
} else if(a_type==value::BOOL) {
|
||||
bool v = false;
|
||||
if(a_v.size()) {if(!tools::to(a_v,v)) return 0;}
|
||||
if(a_v.size()) {if(!to(a_v,v)) return 0;}
|
||||
return new value(v);
|
||||
|
||||
} else if(a_type==value::STRING) {
|
||||
@@ -517,21 +512,21 @@ protected:
|
||||
|
||||
//} else if(a_type==value::UNSIGNED_CHAR) {
|
||||
// unsigned short v = 0;
|
||||
// if(a_v.size()) {if(!tools::to<unsigned short>(a_v,v)) return 0;}
|
||||
// if(a_v.size()) {if(!to<unsigned short>(a_v,v)) return 0;}
|
||||
// return new value((unsigned char)v);
|
||||
|
||||
} else if(a_type==value::UNSIGNED_SHORT) {
|
||||
unsigned short v = 0;
|
||||
if(a_v.size()) {if(!tools::to<unsigned short>(a_v,v)) return 0;}
|
||||
if(a_v.size()) {if(!to<unsigned short>(a_v,v)) return 0;}
|
||||
return new value(v);
|
||||
} else if(a_type==value::UNSIGNED_INT) {
|
||||
unsigned int v = 0;
|
||||
if(a_v.size()) {if(!tools::to<unsigned int>(a_v,v)) return 0;}
|
||||
if(a_v.size()) {if(!to<unsigned int>(a_v,v)) return 0;}
|
||||
return new value(v);
|
||||
|
||||
} else if(a_type==value::UNSIGNED_INT64) {
|
||||
uint64 v = 0;
|
||||
if(a_v.size()) {if(!tools::to<uint64>(a_v,v)) return 0;}
|
||||
if(a_v.size()) {if(!to<uint64>(a_v,v)) return 0;}
|
||||
return new value(v);
|
||||
|
||||
} else if(a_type==value::ARRAY_FLOAT) {
|
||||
|
||||
@@ -23,11 +23,13 @@ inline const std::string& s_cstr() {
|
||||
}
|
||||
#endif
|
||||
|
||||
inline char* str_dup(const char* a_cstr,bool a_inc = true) {
|
||||
inline char* str_dup(const char* a_cstr
|
||||
#ifdef TOOLS_MEM
|
||||
,bool a_inc = true
|
||||
#endif
|
||||
) {
|
||||
#ifdef TOOLS_MEM
|
||||
if(a_inc) mem::increment(s_cstr().c_str());
|
||||
#else
|
||||
(void)a_inc;
|
||||
#endif
|
||||
return ::strcpy((char*)::malloc(::strlen(a_cstr)+1),a_cstr);
|
||||
}
|
||||
|
||||
+24
-53
@@ -1,57 +1,38 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_axis
|
||||
#define tools_axis
|
||||
#ifndef tools_data_axis
|
||||
#define tools_data_axis
|
||||
|
||||
#include "mathf"
|
||||
|
||||
|
||||
namespace tools {
|
||||
|
||||
class axis {
|
||||
class data_axis {
|
||||
public:
|
||||
axis()
|
||||
:m_min_value(0)
|
||||
,m_max_value(0)
|
||||
,m_steps(0)
|
||||
,m_is_log(false)
|
||||
{}
|
||||
virtual ~axis(){}
|
||||
data_axis():m_min_value(0),m_max_value(0),m_is_log(false){}
|
||||
virtual ~data_axis(){}
|
||||
public:
|
||||
axis(const axis& a_from)
|
||||
data_axis(const data_axis& a_from)
|
||||
:m_min_value(a_from.m_min_value)
|
||||
,m_max_value(a_from.m_max_value)
|
||||
,m_steps(a_from.m_steps)
|
||||
,m_is_log(a_from.m_is_log)
|
||||
{}
|
||||
axis& operator=(const axis& a_from){
|
||||
data_axis& operator=(const data_axis& a_from){
|
||||
m_min_value = a_from.m_min_value;
|
||||
m_max_value = a_from.m_max_value;
|
||||
m_steps = a_from.m_steps;
|
||||
m_is_log = a_from.m_is_log;
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
bool is_log(bool a_v){
|
||||
if(m_is_log==a_v) return false;
|
||||
m_is_log = a_v;
|
||||
return true;
|
||||
}
|
||||
bool min_value(float a_v) {
|
||||
if(m_min_value==a_v) return false;
|
||||
m_min_value = a_v;
|
||||
return true;
|
||||
}
|
||||
bool max_value(float a_v) {
|
||||
if(m_max_value==a_v) return false;
|
||||
m_max_value = a_v;
|
||||
return true;
|
||||
}
|
||||
bool is_log(bool a_v) {if(m_is_log==a_v) return false;m_is_log = a_v;return true;}
|
||||
bool min_value(float a_v) {if(m_min_value==a_v) return false;m_min_value = a_v;return true;}
|
||||
bool max_value(float a_v) {if(m_max_value==a_v) return false;m_max_value = a_v;return true;}
|
||||
float min_value() const {return m_min_value;}
|
||||
float max_value() const {return m_max_value;}
|
||||
bool is_log() const {return m_is_log;}
|
||||
|
||||
void adjust_axis() { //from hippodraw.
|
||||
void adjust() { //from hippodraw.
|
||||
int _axis = 0;
|
||||
float step;
|
||||
float mylow, myhigh;
|
||||
@@ -69,10 +50,10 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_steps <= 0) {
|
||||
//if (m_steps <= 0) { //if letting the if and m_steps as a field, twice this function do not give the same result.
|
||||
_axis = 1;
|
||||
m_steps = 10;
|
||||
}
|
||||
unsigned int m_steps = 10;
|
||||
//}
|
||||
|
||||
// Round the "bin width" to a nice number.
|
||||
// If this is being done for an axis (ie m_steps was 0 , then
|
||||
@@ -82,20 +63,15 @@ public:
|
||||
float mag = ffloor(flog10(w));
|
||||
int i = 0;
|
||||
do {
|
||||
step = nice[i] * fpow(10.0,mag);
|
||||
|
||||
step = nice[i] * fpow(10.0,mag);
|
||||
mylow = ffloor(m_min_value/step) * step;
|
||||
myhigh = _axis==1 ? fceil(m_max_value/step) * step :
|
||||
mylow + step * m_steps;
|
||||
|
||||
//myhigh = _axis==1 ? fceil(m_max_value/step) * step : mylow + step * m_steps;
|
||||
myhigh = fceil(m_max_value/step) * step; //quiet Coverity.
|
||||
i++;
|
||||
if (i>=N_NICE) {
|
||||
i = 0;
|
||||
mag++;
|
||||
}
|
||||
if (i>=N_NICE) {i = 0;mag++;}
|
||||
}
|
||||
while ( ( (_axis==1) && myhigh < m_max_value) ||
|
||||
( (_axis==0) && myhigh <= m_max_value) );
|
||||
while ( ( (_axis==1) && (myhigh < m_max_value)) ||
|
||||
( (_axis==0) && (myhigh <= m_max_value)) );
|
||||
|
||||
float range = myhigh - mylow;
|
||||
|
||||
@@ -122,13 +98,10 @@ public:
|
||||
|
||||
// try to round *m_min_value.
|
||||
// correction
|
||||
if( m_is_log && (m_min_value<=0.0)) {
|
||||
m_min_value = 1.0;
|
||||
}
|
||||
if( m_is_log && (m_min_value<=0.0)) m_min_value = 1.0;
|
||||
|
||||
i = N_NICE-1;
|
||||
mag = myhigh != 0.0 ? fceil(flog10(ffabs(myhigh))) :
|
||||
fceil(flog10(ffabs(mylow)));
|
||||
mag = myhigh != 0.0 ? fceil(flog10(ffabs(myhigh))) : fceil(flog10(ffabs(mylow)));
|
||||
|
||||
do {
|
||||
step = nice[i] * fpow(10.0,mag);
|
||||
@@ -147,12 +120,10 @@ public:
|
||||
m_min_value = mylow;
|
||||
m_max_value = myhigh;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
float m_min_value;
|
||||
float m_max_value;
|
||||
int m_steps;
|
||||
//int m_steps;
|
||||
bool m_is_log;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_eqT
|
||||
#define tools_eqT
|
||||
|
||||
namespace tools {
|
||||
|
||||
template <class NUMBER,class PREC>
|
||||
inline bool numbers_are_equal(const NUMBER& a_left,const NUMBER& a_right,const PREC& a_prec,PREC(*a_fabs)(const NUMBER&)) {
|
||||
NUMBER diff = a_left - a_right;
|
||||
if(a_fabs(diff)>=a_prec) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class NUMBER,class PREC>
|
||||
inline bool is_zero(const NUMBER& a_left,const PREC& a_prec,PREC(*a_fabs)(const NUMBER&)) {
|
||||
if(a_fabs(a_left)>=a_prec) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class NUMBER,class PREC>
|
||||
inline bool numbers_are_equal(const NUMBER& a_left,const NUMBER& a_right,const PREC& a_prec,PREC(*a_fabs)(NUMBER)) {
|
||||
NUMBER diff = a_left - a_right;
|
||||
if(a_fabs(diff)>=a_prec) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class VEC,class PREC>
|
||||
inline bool vectors_are_equal(const VEC& a_1,const VEC& a_2,const PREC& a_prec,PREC(*a_fabs)(PREC)) {
|
||||
if(a_1.size()!=a_2.size()) return false;
|
||||
typedef typename VEC::size_type sz_t;
|
||||
sz_t sz = a_1.size();
|
||||
//bool status = true;
|
||||
for(sz_t index=0;index<sz;index++) {
|
||||
if(!numbers_are_equal(a_1[index],a_2[index],a_prec,a_fabs))
|
||||
//{ ::printf("debug : vectors_are_equals : %lu : %g %g\n",index,a_1[index],a_2[index]);
|
||||
return false;
|
||||
//status = false;
|
||||
//}
|
||||
}
|
||||
return true;
|
||||
//return status;
|
||||
}
|
||||
|
||||
template <class VECVEC,class PREC>
|
||||
inline bool vecvecs_are_equal(const VECVEC& a_1,const VECVEC& a_2,const PREC& a_prec,PREC(*a_fabs)(PREC)) {
|
||||
if(a_1.size()!=a_2.size()) return false;
|
||||
typedef typename VECVEC::size_type sz_t;
|
||||
sz_t sz = a_1.size();
|
||||
for(sz_t index=0;index<sz;index++) {
|
||||
if(!vectors_are_equal(a_1[index],a_2[index],a_prec,a_fabs)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -246,11 +246,11 @@ inline bool is_hippo(const std::string& a_file,bool& a_is){
|
||||
char csep;
|
||||
unsigned int number;
|
||||
if(!num_csv_doubles(txt[2],csep,number)) {a_is=false;return true;}
|
||||
std::vector<std::string> words;
|
||||
tools::words(txt[1],"\t",false,words);
|
||||
if(words.size()!=number) {a_is=false;return true;}
|
||||
std::vector<std::string> ws;
|
||||
words(txt[1],"\t",false,ws);
|
||||
if(ws.size()!=number) {a_is=false;return true;}
|
||||
bool all_doubles = true;
|
||||
tools_vforcit(std::string,words,it) {
|
||||
tools_vforcit(std::string,ws,it) {
|
||||
const char* pos = (*it).c_str();
|
||||
char* end;
|
||||
double d = ::strtod(pos,&end);(void)d;
|
||||
|
||||
@@ -31,14 +31,14 @@ inline bool find_with_dirs(std::ostream& a_out,
|
||||
|
||||
if(a_verbose) {
|
||||
a_out << "find_with_dirs :"
|
||||
<< " look for " << tools::sout(a_path) << " ..."
|
||||
<< " look for " << sout(a_path) << " ..."
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
if(tools::file::exists(a_path)) {
|
||||
if(file::exists(a_path)) {
|
||||
if(a_verbose) {
|
||||
a_out << "find_with_dirs :"
|
||||
<< " found " << tools::sout(a_path) << "."
|
||||
<< " found " << sout(a_path) << "."
|
||||
<< std::endl;
|
||||
}
|
||||
return true;
|
||||
@@ -48,7 +48,7 @@ inline bool find_with_dirs(std::ostream& a_out,
|
||||
|
||||
if(a_verbose) {
|
||||
a_out << "find_with_dirs :"
|
||||
<< " " << tools::sout(a_file) << " not found."
|
||||
<< " " << sout(a_file) << " not found."
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
@@ -67,10 +67,10 @@ inline bool find_with_env(std::ostream& a_out,
|
||||
std::string& a_path,
|
||||
bool a_verbose = false ) {
|
||||
std::string PATH;
|
||||
if(!tools::getenv(a_env,PATH)) {
|
||||
if(!get_env(a_env,PATH)) {
|
||||
//look for a a_file in current directory.
|
||||
a_path = a_file;
|
||||
if(tools::file::exists(a_path)) return true;
|
||||
if(file::exists(a_path)) return true;
|
||||
a_out << "tools::find_with_path :"
|
||||
<< " env variable " << sout(a_env) << " not defined."
|
||||
<< std::endl;
|
||||
@@ -79,12 +79,12 @@ inline bool find_with_env(std::ostream& a_out,
|
||||
}
|
||||
if(a_verbose) {
|
||||
a_out << "find_with_path :"
|
||||
<< " PATH is " << tools::sout(PATH)
|
||||
<< " PATH is " << sout(PATH)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
std::vector<std::string> dirs;
|
||||
tools::words(PATH,psep(),false,dirs); //or true ?
|
||||
words(PATH,psep(),false,dirs); //or true ?
|
||||
|
||||
return find_with_dirs(a_out,dirs,a_file,a_path,a_verbose);
|
||||
}
|
||||
|
||||
@@ -49,11 +49,9 @@ inline void cvt_2to3(size_t a_npt,const float* a_xys,float*& a_xyzs) {
|
||||
}
|
||||
|
||||
|
||||
inline void triangle_fan_to_triangles(size_t a_npt,
|
||||
const float* a_fxyzs,const float* a_fnms,
|
||||
float*& a_xyzs,float*& a_nms) {
|
||||
inline void triangle_fan_to_triangles(size_t a_npt,const float* a_fxyzs,float*& a_xyzs) {
|
||||
|
||||
{const float* vpos = a_fxyzs;
|
||||
const float* vpos = a_fxyzs;
|
||||
|
||||
float x1 = *vpos;vpos++;
|
||||
float y1 = *vpos;vpos++;
|
||||
@@ -83,9 +81,13 @@ inline void triangle_fan_to_triangles(size_t a_npt,
|
||||
x2 = x3;
|
||||
y2 = y3;
|
||||
z2 = z3;
|
||||
}}
|
||||
}
|
||||
|
||||
{const float* vpos = a_fnms;
|
||||
}
|
||||
|
||||
inline void triangle_strip_to_triangles(size_t a_npt,const float* a_fxyzs,float*& a_xyzs) {
|
||||
|
||||
const float* vpos = a_fxyzs;
|
||||
|
||||
float x1 = *vpos;vpos++;
|
||||
float y1 = *vpos;vpos++;
|
||||
@@ -96,138 +98,62 @@ inline void triangle_fan_to_triangles(size_t a_npt,
|
||||
float z2 = *vpos;vpos++;
|
||||
|
||||
float x3,y3,z3;
|
||||
bool flip = false;
|
||||
for(size_t i=2;i<a_npt;i++) {
|
||||
x3 = *vpos;vpos++;
|
||||
y3 = *vpos;vpos++;
|
||||
z3 = *vpos;vpos++;
|
||||
*a_nms = x1;a_nms++;
|
||||
*a_nms = y1;a_nms++;
|
||||
*a_nms = z1;a_nms++;
|
||||
|
||||
*a_nms = x2;a_nms++;
|
||||
*a_nms = y2;a_nms++;
|
||||
*a_nms = z2;a_nms++;
|
||||
if(flip) {
|
||||
*a_xyzs = x1;a_xyzs++;
|
||||
*a_xyzs = y1;a_xyzs++;
|
||||
*a_xyzs = z1;a_xyzs++;
|
||||
|
||||
*a_nms = x3;a_nms++;
|
||||
*a_nms = y3;a_nms++;
|
||||
*a_nms = z3;a_nms++;
|
||||
*a_xyzs = x3;a_xyzs++;
|
||||
*a_xyzs = y3;a_xyzs++;
|
||||
*a_xyzs = z3;a_xyzs++;
|
||||
|
||||
*a_xyzs = x2;a_xyzs++;
|
||||
*a_xyzs = y2;a_xyzs++;
|
||||
*a_xyzs = z2;a_xyzs++;
|
||||
} else {
|
||||
*a_xyzs = x1;a_xyzs++;
|
||||
*a_xyzs = y1;a_xyzs++;
|
||||
*a_xyzs = z1;a_xyzs++;
|
||||
|
||||
*a_xyzs = x2;a_xyzs++;
|
||||
*a_xyzs = y2;a_xyzs++;
|
||||
*a_xyzs = z2;a_xyzs++;
|
||||
|
||||
*a_xyzs = x3;a_xyzs++;
|
||||
*a_xyzs = y3;a_xyzs++;
|
||||
*a_xyzs = z3;a_xyzs++;
|
||||
}
|
||||
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
z1 = z2;
|
||||
|
||||
x2 = x3;
|
||||
y2 = y3;
|
||||
z2 = z3;
|
||||
}}
|
||||
|
||||
flip = flip?false:true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void triangle_fan_to_triangles(size_t a_npt,
|
||||
const float* a_fxyzs,const float* a_fnms,
|
||||
float*& a_xyzs,float*& a_nms) {
|
||||
triangle_fan_to_triangles(a_npt,a_fxyzs,a_xyzs);
|
||||
triangle_fan_to_triangles(a_npt,a_fnms,a_nms);
|
||||
}
|
||||
|
||||
inline void triangle_strip_to_triangles(size_t a_npt,
|
||||
const float* a_fxyzs,const float* a_fnms,
|
||||
float*& a_xyzs,float*& a_nms) {
|
||||
|
||||
{const float* vpos = a_fxyzs;
|
||||
|
||||
float x1 = *vpos;vpos++;
|
||||
float y1 = *vpos;vpos++;
|
||||
float z1 = *vpos;vpos++;
|
||||
|
||||
float x2 = *vpos;vpos++;
|
||||
float y2 = *vpos;vpos++;
|
||||
float z2 = *vpos;vpos++;
|
||||
|
||||
float x3,y3,z3;
|
||||
bool flip = false;
|
||||
for(size_t i=2;i<a_npt;i++) {
|
||||
x3 = *vpos;vpos++;
|
||||
y3 = *vpos;vpos++;
|
||||
z3 = *vpos;vpos++;
|
||||
|
||||
if(flip) {
|
||||
*a_xyzs = x1;a_xyzs++;
|
||||
*a_xyzs = y1;a_xyzs++;
|
||||
*a_xyzs = z1;a_xyzs++;
|
||||
|
||||
*a_xyzs = x3;a_xyzs++;
|
||||
*a_xyzs = y3;a_xyzs++;
|
||||
*a_xyzs = z3;a_xyzs++;
|
||||
|
||||
*a_xyzs = x2;a_xyzs++;
|
||||
*a_xyzs = y2;a_xyzs++;
|
||||
*a_xyzs = z2;a_xyzs++;
|
||||
} else {
|
||||
*a_xyzs = x1;a_xyzs++;
|
||||
*a_xyzs = y1;a_xyzs++;
|
||||
*a_xyzs = z1;a_xyzs++;
|
||||
|
||||
*a_xyzs = x2;a_xyzs++;
|
||||
*a_xyzs = y2;a_xyzs++;
|
||||
*a_xyzs = z2;a_xyzs++;
|
||||
|
||||
*a_xyzs = x3;a_xyzs++;
|
||||
*a_xyzs = y3;a_xyzs++;
|
||||
*a_xyzs = z3;a_xyzs++;
|
||||
}
|
||||
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
z1 = z2;
|
||||
|
||||
x2 = x3;
|
||||
y2 = y3;
|
||||
z2 = z3;
|
||||
|
||||
flip = flip?false:true;
|
||||
}}
|
||||
|
||||
{const float* vpos = a_fnms;
|
||||
|
||||
float x1 = *vpos;vpos++;
|
||||
float y1 = *vpos;vpos++;
|
||||
float z1 = *vpos;vpos++;
|
||||
|
||||
float x2 = *vpos;vpos++;
|
||||
float y2 = *vpos;vpos++;
|
||||
float z2 = *vpos;vpos++;
|
||||
|
||||
float x3,y3,z3;
|
||||
bool flip = false;
|
||||
for(size_t i=2;i<a_npt;i++) {
|
||||
x3 = *vpos;vpos++;
|
||||
y3 = *vpos;vpos++;
|
||||
z3 = *vpos;vpos++;
|
||||
|
||||
if(flip) {
|
||||
*a_nms = x1;a_nms++;
|
||||
*a_nms = y1;a_nms++;
|
||||
*a_nms = z1;a_nms++;
|
||||
|
||||
*a_nms = x3;a_nms++;
|
||||
*a_nms = y3;a_nms++;
|
||||
*a_nms = z3;a_nms++;
|
||||
|
||||
*a_nms = x2;a_nms++;
|
||||
*a_nms = y2;a_nms++;
|
||||
*a_nms = z2;a_nms++;
|
||||
} else {
|
||||
*a_nms = x1;a_nms++;
|
||||
*a_nms = y1;a_nms++;
|
||||
*a_nms = z1;a_nms++;
|
||||
|
||||
*a_nms = x2;a_nms++;
|
||||
*a_nms = y2;a_nms++;
|
||||
*a_nms = z2;a_nms++;
|
||||
|
||||
*a_nms = x3;a_nms++;
|
||||
*a_nms = y3;a_nms++;
|
||||
*a_nms = z3;a_nms++;
|
||||
}
|
||||
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
z1 = z2;
|
||||
|
||||
x2 = x3;
|
||||
y2 = y3;
|
||||
z2 = z3;
|
||||
flip = flip?false:true;
|
||||
}}
|
||||
triangle_strip_to_triangles(a_npt,a_fxyzs,a_xyzs);
|
||||
triangle_strip_to_triangles(a_npt,a_fnms,a_nms);
|
||||
}
|
||||
|
||||
inline void triangle_fan_to_triangles_2to3(size_t a_npt,const float* a_xys,float*& a_xyzs) {
|
||||
|
||||
@@ -569,6 +569,9 @@ inline int __gl_meshDelete( GLUhalfEdge *eDel )
|
||||
/* We are joining two loops into one -- remove the left face */
|
||||
joiningLoops = GLU_TRUE;
|
||||
static_KillFace( eDel->Lface, eDel->Rface );
|
||||
/* G.Barrand : note : Coverity says that there is a problem using eDel->Lface->anEdge in the below,
|
||||
but it appears that at the out of the upper static_KillFace() call (then here), eDel->Lface before
|
||||
(the pointer freeed) is not the same than after (then here). */
|
||||
}
|
||||
|
||||
if( eDel->Onext == eDel ) {
|
||||
|
||||
@@ -37,6 +37,9 @@ inline/*static*/ void static_ComputeNormal( GLUtesselator *tess, GLUdouble norm[
|
||||
|
||||
maxVal[0] = maxVal[1] = maxVal[2] = -2 * GLU_TESS_MAX_COORD;
|
||||
minVal[0] = minVal[1] = minVal[2] = 2 * GLU_TESS_MAX_COORD;
|
||||
|
||||
minVert[0] = 0;minVert[1] = 0;minVert[2] = 0; //G.Barrand : to quiet Coverity.
|
||||
maxVert[0] = 0;maxVert[1] = 0;maxVert[2] = 0; //G.Barrand : to quiet Coverity.
|
||||
|
||||
for( v = vHead->next; v != vHead; v = v->next ) {
|
||||
for( i = 0; i < 3; ++i ) {
|
||||
@@ -64,6 +67,7 @@ inline/*static*/ void static_ComputeNormal( GLUtesselator *tess, GLUdouble norm[
|
||||
maxLen2 = 0;
|
||||
v1 = minVert[i];
|
||||
v2 = maxVert[i];
|
||||
if( !v1 || !v2 ) {norm[0] = 0; norm[1] = 0; norm[2] = 1;return;} //G.Barrand.
|
||||
d1[0] = v1->coords[0] - v2->coords[0];
|
||||
d1[1] = v1->coords[1] - v2->coords[1];
|
||||
d1[2] = v1->coords[2] - v2->coords[2];
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#ifndef tools_glutess_rename
|
||||
#define tools_glutess_rename
|
||||
|
||||
/* G.Barrand : namespace protection : */
|
||||
/* G.Barrand : name space protection : */
|
||||
|
||||
#define gluTessBeginContour tools_gluTessBeginContour
|
||||
#define gluTessBeginPolygon tools_gluTessBeginPolygon
|
||||
#define gluTessCallback tools_gluTessCallback
|
||||
|
||||
@@ -1166,7 +1166,13 @@ inline/*static*/ void static_DoneEdgeDict( GLUtesselator *tess )
|
||||
*/
|
||||
if( ! reg->sentinel ) {
|
||||
assert( reg->fixUpperEdge );
|
||||
assert( ++fixedEdges == 1 );
|
||||
//G.Barrand : fix a Coverity diagnostic : begin :
|
||||
//assert( ++fixedEdges == 1 );
|
||||
#ifndef NDEBUG
|
||||
fixedEdges++;
|
||||
#endif
|
||||
assert( fixedEdges == 1 );
|
||||
//G.Barrand : end.
|
||||
}
|
||||
assert( reg->windingNumber == 0 );
|
||||
static_DeleteRegion( tess, reg );
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hatcher
|
||||
#define tools_hatcher
|
||||
|
||||
/**
|
||||
*
|
||||
* hatcher is a class to draw Hatch in a 3D polyline plane
|
||||
* A hatch is caracterise by a direction (dirAngle), a spacing to get
|
||||
* second hatch,
|
||||
* an offset, and a stripWidth :
|
||||
* - offset value : between 0-1, This value set the offset of
|
||||
* the hatch.0 meen that the hatch will touch the first point
|
||||
* of the polyline, and 1 meen that first hatch will be draw
|
||||
* at a 'spacing' distance to first point
|
||||
* - offsetVec : the 3D point from where a hatch had to pass. This is
|
||||
* very usefull to have hach continuing in different polygones
|
||||
*
|
||||
* The compute_polyline() method<br>
|
||||
* By default:
|
||||
* - spacing = .1;
|
||||
* - dirAngle = PI/4;
|
||||
* - offsetValue = 0;
|
||||
* - stripWidth=0.0;
|
||||
*
|
||||
* A way to get all points and vertices and to draw them can be :
|
||||
* <pre>
|
||||
* iindex =0;
|
||||
* icoord =0;
|
||||
* for (unsigned int a=0;a<sbHatch.number_of_vertices();a++) {
|
||||
* for (unsigned int b=0;b<sbHatch.number_of_vertices()[a];b++) {
|
||||
* coordinate3->point.set1Value(icoord,sbHatch.get_points()[icoord]);
|
||||
* indexedFaceSet->coordIndex.set1Value(iindex,icoord);
|
||||
* iindex++;
|
||||
* icoord ++;
|
||||
* }
|
||||
* indexedFaceSet->coordIndex.set1Value(iindex,SO_END_LINE_INDEX);
|
||||
* iindex++;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Laurent Garnier
|
||||
* Creation : on Fri Jan 05 2004
|
||||
* Last update : 9 April 2004
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lina/vec3f"
|
||||
#include "lina/vec2f"
|
||||
#include "mathf"
|
||||
#include <cfloat> // for FLT_MAX
|
||||
|
||||
namespace tools {
|
||||
|
||||
class hatcher {
|
||||
public:
|
||||
hatcher()
|
||||
:fShift(.1f)
|
||||
,fDirAngle(fpi()/4)
|
||||
,fOffsetValue(.0f)
|
||||
,fOffset(vec3f(FLT_MAX,FLT_MAX,FLT_MAX))
|
||||
,fPrecisionFactor (.0001f) // good value to get rid of some errors
|
||||
,fStripWidth(0.0)
|
||||
,fFirstNumHatch(0)
|
||||
,fNumberHatchToDraw(0)
|
||||
,fFirstPolyline(true)
|
||||
,fResolveResult(UNDEFINED)
|
||||
{}
|
||||
virtual ~hatcher() {}
|
||||
protected:
|
||||
hatcher(const hatcher& a_from)
|
||||
:fNormal(a_from.fNormal)
|
||||
,fShift(a_from.fShift)
|
||||
,fDirAngle(a_from.fDirAngle)
|
||||
,fOffsetValue(a_from.fOffsetValue)
|
||||
,fOffset(a_from.fOffset)
|
||||
,fShiftVec(a_from.fShiftVec)
|
||||
,fPrecisionFactor(a_from.fPrecisionFactor)
|
||||
,fDirVec(a_from.fDirVec)
|
||||
,fStripWidth(a_from.fStripWidth)
|
||||
,fPoints(a_from.fPoints)
|
||||
,fVertices(a_from.fVertices)
|
||||
,fConflictNumHatchLineTab(a_from.fConflictNumHatchLineTab)
|
||||
,fHatchShiftToMatchPointVec(a_from.fHatchShiftToMatchPointVec)
|
||||
,fFirstNumHatch(a_from.fFirstNumHatch)
|
||||
,fNumberHatchToDraw(a_from.fNumberHatchToDraw)
|
||||
,fFirstPolyline(a_from.fFirstPolyline)
|
||||
,fResolveResult(a_from.fResolveResult)
|
||||
{}
|
||||
hatcher& operator=(const hatcher& a_from){
|
||||
fNormal = a_from.fNormal;
|
||||
fShift = a_from.fShift;
|
||||
fDirAngle = a_from.fDirAngle;
|
||||
fOffsetValue = a_from.fOffsetValue;
|
||||
fOffset = a_from.fOffset;
|
||||
fShiftVec = a_from.fShiftVec;
|
||||
fPrecisionFactor = a_from.fPrecisionFactor;
|
||||
fDirVec = a_from.fDirVec;
|
||||
fStripWidth = a_from.fStripWidth;
|
||||
fPoints = a_from.fPoints;
|
||||
fVertices = a_from.fVertices;
|
||||
fConflictNumHatchLineTab = a_from.fConflictNumHatchLineTab;
|
||||
fHatchShiftToMatchPointVec = a_from.fHatchShiftToMatchPointVec;
|
||||
fFirstNumHatch = a_from.fFirstNumHatch;
|
||||
fNumberHatchToDraw = a_from.fNumberHatchToDraw;
|
||||
fFirstPolyline = a_from.fFirstPolyline;
|
||||
fResolveResult = a_from.fResolveResult;
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* draw the hatch into the polyline bounding box given in argument
|
||||
* You have to get all compute points by the get_points() method
|
||||
* Number of points can be get by number_of_points()
|
||||
* The number of vertices in the return polyline can be get by number_of_vertices()
|
||||
* and vertice table by get_vertices
|
||||
* @return FALSE if :
|
||||
* - All points are not in the same plan
|
||||
* - There is a precision error on one or more point
|
||||
*/
|
||||
bool compute_polyline (vec3f* listPoints,unsigned int number);
|
||||
|
||||
|
||||
/**
|
||||
* test if the polygone given is correct for hatching
|
||||
* @return FALSE if :
|
||||
* - All points are not in the same plan
|
||||
* - Number of points <3
|
||||
* - Offset point is not in the same plan
|
||||
* - There is less than three different points
|
||||
* - The vector from point[0],point[1] is colinear to point[0],lastPoint
|
||||
*/
|
||||
bool check_polyline(vec3f* listPoints,unsigned int number);
|
||||
|
||||
void set_spacing(float a) {fShift = a;} //set the spacing for this hatch.
|
||||
void set_angle(float a) {fDirAngle = a;} //set the Direction angle for the hatch in radians.
|
||||
void set_offset(float a) {fOffsetValue = a;} //set the offset value for this hatch.
|
||||
void set_offset_point(vec3f a) {fOffset = a;} //set the offset Point for this hatch.
|
||||
void set_precision_factor(float a) {fPrecisionFactor = a;} //set the precision factor for computing (0.0001 is default).
|
||||
|
||||
bool set_strip_width(float a) {
|
||||
// set the strip width value(0 is default and means no strip).
|
||||
if (a<0 || a>1) {
|
||||
fStripWidth = 0;
|
||||
return false;
|
||||
}
|
||||
fStripWidth = a;
|
||||
return true;
|
||||
}
|
||||
|
||||
float get_spacing()const {return fShift;}
|
||||
float get_angle()const {return fDirAngle;}
|
||||
float get_offset()const {return fOffsetValue;}
|
||||
const vec3f& get_offset_point() {return fOffset;}
|
||||
float get_precision_factor()const {return fPrecisionFactor;}
|
||||
float get_strip_width()const {return fStripWidth;}
|
||||
const vec3f& get_normal() {return fNormal;}
|
||||
|
||||
//size_t number_of_points() const {return fPoints.size();} //get the number of points compute for this hatch.
|
||||
/** vector of compute points<br>
|
||||
* Be careful with this function because it can return a set of non convex
|
||||
* polygone if you have a non convex polygone at beginning !So, when you want
|
||||
* to draw it, you have to use a tesselisation algorithm first
|
||||
*/
|
||||
const std::vector<vec3f>& points() {return fPoints;}
|
||||
|
||||
//size_t number_of_vertices() const {return fVertices.size();} //get the number of vertices compute for this hatch.
|
||||
/** vector of numbers of vertices */
|
||||
const std::vector<unsigned int>& vertices() {return fVertices;}
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* draw the hatch into the polyline bounding box given in argument
|
||||
* @return FALSE if :
|
||||
* - All points are not in the same plan
|
||||
* - There is a precision error on one or more point
|
||||
*/
|
||||
bool compute_single_polyline (vec3f* listPoints,unsigned int number);
|
||||
|
||||
|
||||
/**
|
||||
* Compute a vector system equation aA+bB=C
|
||||
* return SbVec2f(0,0) if there is an error
|
||||
* set the resolveResult variable to the error code :
|
||||
* COLINEAR if A and B are
|
||||
* PRECISION_ERROR if there is a lack of precision in computing
|
||||
* Z_ERROR if there s no solution for Z
|
||||
* UNDEFINED never throw
|
||||
* return a SbVec2f for result. a is 'x' value and b is 'y' if it is correct
|
||||
*/
|
||||
vec2f resolve_system(const vec3f& A,const vec3f& B,const vec3f& C);
|
||||
|
||||
|
||||
protected:
|
||||
/** normal vector for the current polyline */
|
||||
vec3f fNormal;
|
||||
|
||||
/** Spacing vector between two hatch */
|
||||
float fShift; // Absloute distance between two hatch in the polyline plan */
|
||||
|
||||
/** The angle (given in radians) is the one between the first
|
||||
* line (point 1-point0) and the hatch lines, in the polyline plan.
|
||||
* Given in the direct axis ((point1-point0),(lastPoint-point0),
|
||||
* normalPlanVec). The angle in compute only one time for the first polyline.
|
||||
* Changes on angle value for others polyline will not take effect.This is to
|
||||
* perform correct hatching between the polylines
|
||||
*/
|
||||
float fDirAngle;
|
||||
|
||||
/** between 0-1. This value set the offset of the hatch.0 meen
|
||||
* that the hatch will touch the first point of the polyline,
|
||||
* and 1 meen that first hatch will be draw
|
||||
* at a 'spacing' distance to first point
|
||||
*/
|
||||
float fOffsetValue;
|
||||
|
||||
/** first point of the hatch.
|
||||
* offset = firstPolylinePoint+ShiftVec*offsetValue
|
||||
*/
|
||||
vec3f fOffset;
|
||||
|
||||
/** Orientation vector for the hatch */
|
||||
vec3f fShiftVec;
|
||||
|
||||
/** factor for compute error between two points */
|
||||
float fPrecisionFactor;
|
||||
|
||||
/** hatch direction Vector */
|
||||
vec3f fDirVec;
|
||||
|
||||
/** strip with size : set to 0 by default
|
||||
* between 0 and 1.0 means no strip, 0.5 means strip size is
|
||||
* half of distance between two hatches
|
||||
*/
|
||||
float fStripWidth;
|
||||
|
||||
/** vector list of points */
|
||||
std::vector<vec3f> fPoints;
|
||||
|
||||
/** vector vertices number */
|
||||
std::vector<unsigned int> fVertices;
|
||||
|
||||
/** conflict line table */
|
||||
std::vector< std::vector<int> > fConflictNumHatchLineTab;
|
||||
|
||||
/** hatchShiftToMatchPointVec tab*/
|
||||
std::vector<float> fHatchShiftToMatchPointVec;
|
||||
|
||||
/** first hatch number to draw */
|
||||
int fFirstNumHatch;
|
||||
|
||||
/**number of hatch to draw */
|
||||
unsigned int fNumberHatchToDraw;
|
||||
|
||||
bool fFirstPolyline;
|
||||
enum ResolveErrors{
|
||||
OK = 0,
|
||||
COLINEAR,
|
||||
Z_ERROR,
|
||||
PRECISION_ERROR,
|
||||
UNDEFINED
|
||||
};
|
||||
ResolveErrors fResolveResult;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "hatcher.icc"
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,975 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_T_tools
|
||||
#define tools_hdf5_T_tools
|
||||
|
||||
#include "hdf5_h"
|
||||
|
||||
#include <tools/typedefs>
|
||||
#include <tools/forit>
|
||||
#include <tools/num2s>
|
||||
#include <tools/vdata>
|
||||
//#include <map>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline hid_t to_T_file_type(char) {return H5T_STD_I8LE;} //H5T_STD_I8XX()
|
||||
inline hid_t to_T_file_type(short) {return H5T_STD_I16LE;} //HST_STD_I16XX()
|
||||
inline hid_t to_T_file_type(int) {return H5T_STD_I32LE;} //H5T_STD_I32XX()
|
||||
inline hid_t to_T_file_type(tools::int64) {return H5T_STD_I64LE;} //H5T_STD_I64XX()
|
||||
|
||||
inline hid_t to_T_file_type(float) {return H5T_IEEE_F32LE;} //H5T_IEEE_F32XX()
|
||||
inline hid_t to_T_file_type(double) {return H5T_IEEE_F64LE;} //H5T_IEEE_F64XX()
|
||||
|
||||
inline hid_t to_T_file_type(unsigned char) {return H5T_STD_U8LE;}
|
||||
inline hid_t to_T_file_type(unsigned short) {return H5T_STD_U16LE;}
|
||||
inline hid_t to_T_file_type(unsigned int) {return H5T_STD_U32LE;}
|
||||
inline hid_t to_T_file_type(tools::uint64) {return H5T_STD_U64LE;}
|
||||
|
||||
inline hid_t to_T_mem_type(char) {return H5T_NATIVE_CHAR;}
|
||||
inline hid_t to_T_mem_type(short) {return H5T_NATIVE_SHORT;}
|
||||
inline hid_t to_T_mem_type(int) {return H5T_NATIVE_INT;}
|
||||
inline hid_t to_T_mem_type(tools::int64) {return H5T_NATIVE_INT64;}
|
||||
|
||||
inline hid_t to_T_mem_type(float) {return H5T_NATIVE_FLOAT;}
|
||||
inline hid_t to_T_mem_type(double) {return H5T_NATIVE_DOUBLE;}
|
||||
|
||||
inline hid_t to_T_mem_type(unsigned char) {return H5T_NATIVE_UCHAR;}
|
||||
inline hid_t to_T_mem_type(unsigned short) {return H5T_NATIVE_USHORT;}
|
||||
inline hid_t to_T_mem_type(unsigned int) {return H5T_NATIVE_UINT;}
|
||||
inline hid_t to_T_mem_type(tools::uint64) {return H5T_NATIVE_UINT64;}
|
||||
|
||||
template <class T>
|
||||
inline bool write_array(hid_t a_loc,const std::string& a_name,
|
||||
hid_t a_file_type,hid_t a_mem_type,
|
||||
unsigned int a_chunked,unsigned int a_compress,
|
||||
unsigned int a_size,const T a_array[]) {
|
||||
if(!a_size) return false;
|
||||
|
||||
hid_t cpt = -1;
|
||||
if(a_compress || a_chunked) {
|
||||
cpt = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(cpt<0) return false;
|
||||
if(a_chunked) {
|
||||
if(H5Pset_layout(cpt,H5D_CHUNKED)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
hsize_t cdims[1];
|
||||
cdims[0] = a_chunked;
|
||||
if(H5Pset_chunk(cpt,1,cdims)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(H5Pset_layout(cpt,H5D_COMPACT)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(a_compress) {
|
||||
if(H5Pset_deflate(cpt,a_compress>9?9:a_compress)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpt = H5P_DEFAULT;
|
||||
}
|
||||
|
||||
hid_t dataset = -1;
|
||||
|
||||
{hsize_t dims[1];
|
||||
dims[0] = a_size;
|
||||
hid_t file_space = -1;
|
||||
if(a_chunked) {
|
||||
hsize_t mx_dims[1];
|
||||
mx_dims[0] = H5S_UNLIMITED; //extendable.
|
||||
file_space = ::H5Screate_simple(1,dims,mx_dims);
|
||||
} else {
|
||||
file_space = ::H5Screate_simple(1,dims,NULL);
|
||||
}
|
||||
if(file_space<0) {if(cpt>=0) ::H5Pclose(cpt);return false;}
|
||||
dataset = tools_H5Dcreate(a_loc,a_name.c_str(),a_file_type,file_space,cpt);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
::H5Sclose(file_space);
|
||||
if(dataset<0) return false;}
|
||||
|
||||
if(H5Dwrite(dataset,a_mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,a_array)<0) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
::H5Dclose(dataset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool write_sub_array(hid_t a_loc,const std::string& a_name,
|
||||
hid_t a_file_type,hid_t a_mem_type,
|
||||
bool a_create,
|
||||
unsigned int a_chunked,unsigned int a_compress, // used if a_creat = true;
|
||||
unsigned int a_size,
|
||||
unsigned int a_offset,unsigned int a_number,const T a_array[]) {
|
||||
|
||||
int remain = a_size-a_offset;
|
||||
int number = (int(a_number)<=remain) ? int(a_number) : remain;
|
||||
if(number<=0) return false;
|
||||
|
||||
hid_t cpt = -1;
|
||||
|
||||
if(a_create) {
|
||||
if(a_compress || a_chunked) {
|
||||
cpt = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(cpt<0) return false;
|
||||
if(a_chunked) {
|
||||
if(H5Pset_layout(cpt,H5D_CHUNKED)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
hsize_t cdims[1];
|
||||
//cdims[0] = (a_size<=32?a_size:32);
|
||||
cdims[0] = a_chunked;
|
||||
if(H5Pset_chunk(cpt,1,cdims)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(H5Pset_layout(cpt,H5D_COMPACT)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(a_compress) {
|
||||
if(H5Pset_deflate(cpt,a_compress>9?9:a_compress)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpt = H5P_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
hid_t dataset = -1;
|
||||
|
||||
hid_t file_space = -1;
|
||||
|
||||
if(a_create) {
|
||||
hsize_t dims[1];
|
||||
dims[0] = a_size;
|
||||
file_space = ::H5Screate_simple(1,dims,NULL);
|
||||
if(file_space<0) {
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
{hsize_t offset[1];
|
||||
offset[0] = a_offset;
|
||||
hsize_t count[1];
|
||||
count[0] = number;
|
||||
if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}}
|
||||
|
||||
dataset = tools_H5Dcreate(a_loc,a_name.c_str(),a_file_type,file_space,cpt);
|
||||
if(dataset<0) {
|
||||
::H5Sclose(file_space);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else { //open an existing dataset :
|
||||
dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
{hsize_t offset[1];
|
||||
offset[0] = a_offset;
|
||||
hsize_t count[1];
|
||||
count[0] = number;
|
||||
if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}}
|
||||
|
||||
}
|
||||
|
||||
hsize_t dims[1];
|
||||
dims[0] = number;
|
||||
hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dwrite(dataset,a_mem_type,mem_space,file_space,H5P_DEFAULT,a_array)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool write_append_array_dataset(hid_t a_dataset,hid_t /*a_file_type*/,hid_t a_mem_type,
|
||||
unsigned int a_number,const T a_array[]) {
|
||||
hsize_t old_size = 0;
|
||||
|
||||
{hid_t dataspace = H5Dget_space(a_dataset);
|
||||
if(dataspace<0) return false;
|
||||
hsize_t dims[1];
|
||||
if(H5Sget_simple_extent_dims(dataspace,dims,NULL)<0) {
|
||||
::H5Sclose(dataspace);
|
||||
return false;
|
||||
}
|
||||
old_size = dims[0];
|
||||
::H5Sclose(dataspace);}
|
||||
|
||||
{hsize_t exts[1];
|
||||
exts[0] = old_size+a_number;
|
||||
// if(H5Dextend(dataset,exts)<0) {
|
||||
if(H5Dset_extent(a_dataset,exts)<0) return false;}
|
||||
|
||||
hid_t file_space = H5Dget_space(a_dataset);
|
||||
if(file_space<0) return false;
|
||||
|
||||
{hsize_t offset[1];
|
||||
offset[0] = old_size;
|
||||
hsize_t count[1];
|
||||
count[0] = a_number;
|
||||
if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
return false;
|
||||
}}
|
||||
|
||||
hsize_t dims[1];
|
||||
dims[0] = a_number;
|
||||
hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dwrite(a_dataset,a_mem_type,mem_space,file_space,H5P_DEFAULT,a_array)<0) {
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool write_append_array(hid_t a_loc,const std::string& a_name,hid_t a_file_type,hid_t a_mem_type,
|
||||
unsigned int a_number,const T a_array[]) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) return false;
|
||||
bool status = write_append_array_dataset(dataset,a_file_type,a_mem_type,a_number,a_array);
|
||||
::H5Dclose(dataset);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
template <class T>
|
||||
inline bool write_array_struct(
|
||||
hid_t a_loc
|
||||
,const std::string& a_name
|
||||
,hid_t a_create_type
|
||||
,hid_t aWriteType
|
||||
,unsigned int a_size
|
||||
,const T a_array[]
|
||||
){
|
||||
hsize_t dims[1];
|
||||
dims[0] = a_size;
|
||||
hid_t dataspace = ::H5Screate_simple(1,dims,NULL);
|
||||
if(dataspace<0) return false;
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),a_create_type,dataspace,H5P_DEFAULT);
|
||||
if(dataset<0) {
|
||||
::H5Sclose(dataspace);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dwrite(dataset,aWriteType,H5S_ALL,H5S_ALL,H5P_DEFAULT,a_array)<0) {
|
||||
::H5Dclose(dataset);
|
||||
::H5Sclose(dataspace);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Dclose(dataset);
|
||||
::H5Sclose(dataspace);
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
inline bool read_scalar(hid_t a_loc,const std::string& a_name,hid_t a_mem_type,T& a_data) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) return false;
|
||||
|
||||
hid_t file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t mem_space = ::H5Screate(H5S_SCALAR);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dread(dataset,a_mem_type,mem_space,file_space,H5P_DEFAULT,&a_data)<0) {
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool read_array(hid_t a_loc,const std::string& a_name,hid_t a_mem_type,unsigned int& a_size,T*& a_array,bool a_alloc = true) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false; // data set not found.
|
||||
}
|
||||
|
||||
hid_t file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
{int dimn = H5Sget_simple_extent_ndims(file_space);
|
||||
if(dimn<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}
|
||||
if(dimn!=1) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}
|
||||
//printf("debug : read dimn %d\n",dimn);
|
||||
}
|
||||
|
||||
hsize_t dims[1];
|
||||
{if(H5Sget_simple_extent_dims(file_space,dims,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
a_size = (unsigned int)dims[0];
|
||||
if(!a_size) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return true; //It is ok.
|
||||
}
|
||||
|
||||
hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(a_alloc) a_array = new T[a_size];
|
||||
if(H5Dread(dataset,a_mem_type,mem_space,file_space,H5P_DEFAULT,a_array)<0) {
|
||||
if(a_alloc) delete [] a_array;
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool read_sub_array(hid_t a_loc,const std::string& a_name,hid_t a_mem_type,
|
||||
unsigned int a_offset,unsigned int a_number,
|
||||
unsigned int& a_size,T*& a_array) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false; // data set not found.
|
||||
}
|
||||
|
||||
hid_t file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
{int dimn = H5Sget_simple_extent_ndims(file_space);
|
||||
if(dimn<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
if(dimn!=1) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
//printf("debug : read dimn %d\n",dimn);
|
||||
}
|
||||
|
||||
hsize_t dims[1];
|
||||
{if(H5Sget_simple_extent_dims(file_space,dims,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
unsigned int sz = (unsigned int)dims[0];
|
||||
if(!sz) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return true; //It is ok.
|
||||
}
|
||||
|
||||
// abcdef
|
||||
// 012345
|
||||
int remain = sz-a_offset;
|
||||
int number = (int(a_number)<=remain) ? int(a_number) : remain;
|
||||
if(number<=0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return true; //It is ok.
|
||||
}
|
||||
|
||||
{hsize_t offset[1];
|
||||
offset[0] = a_offset;
|
||||
hsize_t count[1];
|
||||
count[0] = number;
|
||||
if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
dims[0] = number;
|
||||
hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
a_array = new T[number];
|
||||
if(H5Dread(dataset,a_mem_type,mem_space,file_space,H5P_DEFAULT,a_array)<0) {
|
||||
delete [] a_array;
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
a_size = number;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_scalar(hid_t a_loc,const std::string& a_name,TYPE& aValue) {
|
||||
return read_scalar<TYPE>(a_loc,a_name,to_T_mem_type(TYPE()),aValue);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool read_std_vec(hid_t a_loc,const std::string& a_name,hid_t a_mem_type,std::vector<T>& a_vec) {
|
||||
tools::uint64 sz;
|
||||
if(!read_scalar<tools::uint64>(a_loc,a_name+"_size",sz)) return false;
|
||||
if(!sz) {a_vec.clear();return true;} //it is ok.
|
||||
a_vec.resize((size_t)sz);
|
||||
T* data = tools::vec_data(a_vec);
|
||||
unsigned int _sz;
|
||||
if(!read_array(a_loc,a_name,a_mem_type,_sz,data,false)) return false; //false = do not alloc.
|
||||
if(tools::uint64(_sz)!=sz) {a_vec.clear();return false;}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_std_vec_vec(hid_t a_loc,const std::string& a_name,hid_t a_mem_type,std::vector< std::vector<TYPE> >& a_vec_vec) {
|
||||
tools::uint64 sz;
|
||||
if(!read_scalar<tools::uint64>(a_loc,a_name+"_size",sz)) {a_vec_vec.clear();return false;}
|
||||
a_vec_vec.resize((size_t)sz);
|
||||
std::string scount;
|
||||
for(size_t count=0;count<(size_t)sz;count++) {
|
||||
tools::num2s(count,scount);
|
||||
if(!read_std_vec<TYPE>(a_loc,a_name+"_elem_"+scount,a_mem_type,a_vec_vec[count])) {a_vec_vec.clear();return false;}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
template <class T>
|
||||
inline bool read_array_struct(
|
||||
hid_t a_loc
|
||||
,const std::string& a_name
|
||||
,hid_t aReadType
|
||||
,unsigned int& a_size
|
||||
,T*& a_array
|
||||
){
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false; // data set not found.
|
||||
}
|
||||
|
||||
hid_t dataspace = H5Dget_space(dataset);
|
||||
if(dataspace<0) {
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int dimn = H5Sget_simple_extent_ndims(dataspace);
|
||||
if(dimn<0) {
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
//printf("debug : read dimn %d\n",dimn);
|
||||
|
||||
hsize_t* dims = new hsize_t[dimn];
|
||||
{int rdimn = H5Sget_simple_extent_dims(dataspace,dims,NULL);
|
||||
if(rdimn<0) {
|
||||
delete [] dims;
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
hid_t memspace = ::H5Screate_simple(dimn,dims,NULL);
|
||||
if(memspace<0) {
|
||||
delete [] dims;
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
a_size = (unsigned int)dims[0];
|
||||
delete [] dims;
|
||||
if(!a_size) {
|
||||
::H5Sclose(memspace);
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
a_array = new T[a_size];
|
||||
if(H5Dread(dataset,aReadType,memspace,dataspace,H5P_DEFAULT,a_array)<0) {
|
||||
delete [] a_array;
|
||||
::H5Sclose(memspace);
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(memspace);
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
inline bool read_struct(hid_t a_loc,const std::string& a_name,hid_t aReadType,T& a_data) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) return false;
|
||||
|
||||
hid_t file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t mem_space = ::H5Screate(H5S_SCALAR);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dread(dataset,aReadType,mem_space,file_space,H5P_DEFAULT,&a_data)<0) {
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_scalar(hid_t a_loc,const std::string& a_name,const TYPE& aData) {
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(compact<0) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Pset_layout(compact,H5D_COMPACT)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),to_T_file_type(TYPE()),scalar,compact);
|
||||
if(dataset<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(::H5Dwrite(dataset,to_T_mem_type(TYPE()),H5S_ALL,H5S_ALL,H5P_DEFAULT,&aData)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool write_struct(hid_t a_loc,const std::string& a_name,
|
||||
hid_t a_create_type,hid_t aWriteType,const T& aData) {
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(compact<0) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Pset_layout(compact,H5D_COMPACT)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),a_create_type,scalar,compact);
|
||||
if(dataset<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dwrite(dataset,aWriteType,H5S_ALL,H5S_ALL,H5P_DEFAULT,&aData)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
template <class TYPE>
|
||||
inline bool write_array(hid_t a_loc,const std::string& a_name,
|
||||
unsigned int a_size,const TYPE a_array[],
|
||||
unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
return hdf5::write_array<TYPE>(a_loc,a_name,to_T_file_type(TYPE()),to_T_mem_type(TYPE()),
|
||||
a_chunked,a_compress,a_size,a_array);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool write_std_vec(hid_t a_loc,const std::string& a_name,
|
||||
hid_t a_file_type,hid_t a_mem_type,
|
||||
unsigned int a_chunked,unsigned int a_compress,
|
||||
const std::vector<T>& a_vec) {
|
||||
if(!write_scalar<tools::uint64>(a_loc,a_name+"_size",a_vec.size())) return false;
|
||||
if(a_vec.empty()) return true; //it is ok.
|
||||
const T* data = tools::vec_data(a_vec);
|
||||
return write_array(a_loc,a_name,a_file_type,a_mem_type,a_chunked,a_compress,a_vec.size(),data);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_std_vec(hid_t a_loc,const std::string& a_name,const std::vector<TYPE>& a_array,
|
||||
unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
return hdf5::write_std_vec<TYPE>(a_loc,a_name,to_T_file_type(TYPE()),to_T_mem_type(TYPE()),a_chunked,a_compress,a_array);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_std_vec_vec(hid_t a_loc,const std::string& a_name,const std::vector< std::vector<TYPE> >& a_vec_vec,
|
||||
unsigned int /*a_chunked*/ = 0,unsigned int /*a_compress*/ = 0) {
|
||||
if(!write_scalar<tools::uint64>(a_loc,a_name+"_size",a_vec_vec.size())) return false;
|
||||
size_t count = 0;
|
||||
std::string scount;
|
||||
tools_typename_vforcit(std::vector<TYPE>,a_vec_vec,it) {
|
||||
tools::num2s(count,scount);
|
||||
if(!write_std_vec<TYPE>(a_loc,a_name+"_elem_"+scount,*it)) return false;
|
||||
count++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//template <class TKEY,class TVALUE>
|
||||
//inline bool write_std_map(hid_t a_loc,const std::string& a_name,const std::map<TKEY,TVALUE>& a_map,
|
||||
// unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
// if(!write_scalar<tools::uint64>(a_loc,a_name+"_size",a_map.size())) return false;
|
||||
// size_t count = 0;
|
||||
// std::string scount;
|
||||
// inlib_typename_mforcit(TKEY,TVALUE,a_map,it) {
|
||||
// tools::num2s(count,scount);
|
||||
// if(!write_scalar<TKEY>(a_loc,a_name+"_elem_"+scount+"_first",(*it).first)) return false;
|
||||
// if(!write_scalar<TVALUE>(a_loc,a_name+"_elem_"+scount+"_secon",(*it).second)) return false;
|
||||
// count++;
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_sub_array(hid_t a_loc,const std::string& a_name,
|
||||
unsigned int a_size,unsigned int a_offset,unsigned int a_number,const TYPE a_array[],
|
||||
bool a_create = true,unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
return hdf5::write_sub_array<TYPE>(a_loc,a_name,to_T_file_type(TYPE()),to_T_mem_type(TYPE()),
|
||||
a_create,a_chunked,a_compress,
|
||||
a_size,a_offset,a_number,a_array);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_append_array_dataset(hid_t a_dataset,unsigned int a_number,const TYPE a_array[]) {
|
||||
return hdf5::write_append_array_dataset<TYPE>(a_dataset,to_T_file_type(TYPE()),to_T_mem_type(TYPE()),a_number,a_array);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_append_array(hid_t a_loc,const std::string& a_name,unsigned int a_number,const TYPE a_array[]) {
|
||||
return hdf5::write_append_array<TYPE>(a_loc,a_name,to_T_file_type(TYPE()),to_T_mem_type(TYPE()),a_number,a_array);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_array(hid_t a_loc,const std::string& a_name,unsigned int& a_size,TYPE*& a_array) {
|
||||
return read_array<TYPE>(a_loc,a_name,to_T_mem_type(TYPE()),a_size,a_array);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_std_vec(hid_t a_loc,const std::string& a_name,std::vector<TYPE>& a_vec) {
|
||||
return read_std_vec<TYPE>(a_loc,a_name,to_T_mem_type(TYPE()),a_vec);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_std_vec_vec(hid_t a_loc,const std::string& a_name,std::vector< std::vector<TYPE> >& a_vec_vec) {
|
||||
return read_std_vec_vec<TYPE>(a_loc,a_name,to_T_mem_type(TYPE()),a_vec_vec);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_sub_array(hid_t a_loc,const std::string& a_name,unsigned int a_offset,unsigned int a_number,
|
||||
unsigned int& a_size,TYPE*& a_array) {
|
||||
return read_sub_array<TYPE>(a_loc,a_name,to_T_mem_type(TYPE()),a_offset,a_number,a_size,a_array);
|
||||
}
|
||||
|
||||
inline bool read_bool(hid_t a_loc,const std::string& a_name,bool& aValue) {
|
||||
unsigned char value = 0;
|
||||
if(!read_scalar<unsigned char>(a_loc,a_name,H5T_NATIVE_UCHAR,value)) {
|
||||
aValue = false;
|
||||
return false;
|
||||
}
|
||||
if((value!=0) && (value!=1)) {
|
||||
aValue = false;
|
||||
return false;
|
||||
}
|
||||
aValue = (value==1?true:false);
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#include "atb"
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_scalar_atb(hid_t aDS,const std::string& a_name,const TYPE& aData) {
|
||||
int has_attr = H5LT_find_attribute(aDS,a_name.c_str());
|
||||
if(has_attr==1) {
|
||||
if(H5Adelete(aDS,a_name.c_str())<0) return false;
|
||||
}
|
||||
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
hid_t aid = tools_H5Acreate(aDS,a_name.c_str(),H5T_STD_I32LE,scalar,H5P_DEFAULT);
|
||||
if(aid<0) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Awrite(aid,H5T_NATIVE_INT,&aData)<0) {
|
||||
::H5Sclose(scalar);
|
||||
::H5Aclose(aid);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(scalar);
|
||||
::H5Aclose(aid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
/*
|
||||
#include <tools/buf2lines>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool write_strings(hid_t a_loc,const std::string& a_name,
|
||||
size_t a_number,const char** a_strings,
|
||||
unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
size_t sz;char* buffer;
|
||||
if(!tools::strings2buf(a_number,a_strings,sz,buffer)) return false;
|
||||
sz--;
|
||||
bool status = hdf5::write_array<char>(a_loc,a_name,to_T_file_type(char()),to_T_mem_type(char()),
|
||||
a_chunked,a_compress,(unsigned int)sz,buffer);
|
||||
delete [] buffer;
|
||||
return status;
|
||||
}
|
||||
|
||||
inline bool write_strings(hid_t a_loc,const std::string& a_name,
|
||||
const std::vector<std::string>& a_strings,
|
||||
unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
size_t sz;char* buffer;
|
||||
if(!tools::strings2buf(a_strings,sz,buffer)) return false;
|
||||
sz--;
|
||||
bool status = hdf5::write_array<char>(a_loc,a_name,to_T_file_type(char()),to_T_mem_type(char()),
|
||||
a_chunked,a_compress,(unsigned int)sz,buffer);
|
||||
delete [] buffer;
|
||||
return status;
|
||||
}
|
||||
|
||||
inline bool write_append_strings(hid_t a_loc,const std::string& a_name,size_t a_number,const char** a_strings) {
|
||||
size_t sz;char* buffer;
|
||||
if(!tools::strings2buf(a_number,a_strings,sz,buffer)) return false;
|
||||
sz--;
|
||||
bool status = hdf5::write_append_array<char>(a_loc,a_name,to_T_file_type(char()),to_T_mem_type(char()),(unsigned int)sz,buffer);
|
||||
delete [] buffer;
|
||||
return status;
|
||||
}
|
||||
|
||||
inline bool write_append_strings(hid_t a_loc,const std::string& a_name,const std::vector<std::string>& a_strings) {
|
||||
size_t sz;char* buffer;
|
||||
if(!tools::strings2buf(a_strings,sz,buffer)) return false;
|
||||
sz--;
|
||||
bool status = hdf5::write_append_array<char>(a_loc,a_name,to_T_file_type(char()),to_T_mem_type(char()),(unsigned int)sz,buffer);
|
||||
delete [] buffer;
|
||||
return status;
|
||||
}
|
||||
|
||||
}}
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_atb
|
||||
#define tools_hdf5_atb
|
||||
|
||||
// The below is internal methods in the HDF5 lib.
|
||||
|
||||
#include "hdf5_h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline herr_t H5LT_get_attribute_mem(hid_t obj_id,const char *attr_name,hid_t mem_type_id,void *data ) {
|
||||
hid_t attr_id;
|
||||
if ( ( attr_id = ::H5Aopen_name( obj_id, attr_name ) ) < 0 ) return -1;
|
||||
if ( ::H5Aread( attr_id, mem_type_id, data ) < 0 ) {
|
||||
::H5Aclose( attr_id );
|
||||
return -1;
|
||||
}
|
||||
if ( ::H5Aclose( attr_id ) < 0 ) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline herr_t find_attr( hid_t loc_id, const char *name, void *op_data) {
|
||||
int ret = 0;
|
||||
char *attr_name = (char*)op_data;
|
||||
if( ::strcmp( name, attr_name ) == 0 ) ret = 1;
|
||||
(void)loc_id;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline herr_t H5LT_find_attribute( hid_t loc_id, const char* attr_name ) {
|
||||
unsigned int attr_num;
|
||||
attr_num = 0;
|
||||
return tools_H5Aiterate( loc_id, &attr_num, find_attr, (void *)attr_name );
|
||||
}
|
||||
|
||||
inline herr_t H5LT_get_attribute_disk( hid_t loc_id,const char *attr_name,void *attr_out ) {
|
||||
hid_t attr_id;
|
||||
if ( ( attr_id = ::H5Aopen_name( loc_id, attr_name ) ) < 0 ) return -1;
|
||||
|
||||
hid_t attr_type;
|
||||
if ( (attr_type = ::H5Aget_type( attr_id )) < 0 ) {
|
||||
::H5Tclose( attr_type );
|
||||
::H5Aclose( attr_id );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ::H5Aread( attr_id, attr_type, attr_out ) < 0 ) {
|
||||
::H5Tclose( attr_type );
|
||||
::H5Aclose( attr_id );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ::H5Tclose( attr_type ) < 0 ) {
|
||||
::H5Tclose( attr_type );
|
||||
::H5Aclose( attr_id );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ::H5Aclose( attr_id ) < 0 ) return -1;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,304 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_h2file
|
||||
#define tools_hdf5_h2file
|
||||
|
||||
#include "tools"
|
||||
#include "T_tools"
|
||||
|
||||
#include <tools/histo/histo_data>
|
||||
#include <tools/sout>
|
||||
#include <ostream>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
}}
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool write_std_map_ss(hid_t a_loc,const std::string& a_name,const std::map<std::string,std::string>& a_map,
|
||||
unsigned int /*a_chunked*/ = 0,unsigned int /*a_compress*/ = 0) {
|
||||
if(!write_scalar<tools::uint64>(a_loc,a_name+"_size",a_map.size())) return false;
|
||||
size_t count = 0;
|
||||
std::string scount;
|
||||
tools_mforcit(std::string,std::string,a_map,it) {
|
||||
tools::num2s(count,scount);
|
||||
if(!write_string(a_loc,a_name+"_elem_"+scount+"_first",(*it).first)) return false;
|
||||
if(!write_string(a_loc,a_name+"_elem_"+scount+"_secon",(*it).second)) return false;
|
||||
count++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_std_map_ss(hid_t a_loc,const std::string& a_name,std::map<std::string,std::string>& a_map,
|
||||
unsigned int /*a_chunked*/ = 0,unsigned int /*a_compress*/ = 0) {
|
||||
a_map.clear();
|
||||
tools::uint64 sz;
|
||||
if(!read_scalar<tools::uint64>(a_loc,a_name+"_size",sz)) return false;
|
||||
std::string scount,key,value;
|
||||
for(tools::uint64 count=0;count<sz;count++) {
|
||||
tools::num2s(count,scount);
|
||||
if(!read_string(a_loc,a_name+"_elem_"+scount+"_first",key)) return false;
|
||||
if(!read_string(a_loc,a_name+"_elem_"+scount+"_secon",value)) return false;
|
||||
a_map[key] = value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef tools::histo::histo_data<double,unsigned int,unsigned int,double> histo_data_t;
|
||||
|
||||
inline bool write_hdata(hid_t a_loc,const histo_data_t& a_hdata) {
|
||||
|
||||
if(!write_string(a_loc,"title",a_hdata.m_title)) return false;
|
||||
if(!write_scalar<unsigned int>(a_loc,"dimension",a_hdata.m_dimension)) return false;
|
||||
if(!write_scalar<unsigned int>(a_loc,"bin_number",a_hdata.m_bin_number)) return false;
|
||||
|
||||
if(!write_std_vec<unsigned int>(a_loc,"bin_entries",a_hdata.m_bin_entries)) return false;
|
||||
if(!write_std_vec<double>(a_loc,"bin_Sw",a_hdata.m_bin_Sw)) return false;
|
||||
if(!write_std_vec<double>(a_loc,"bin_Sw2",a_hdata.m_bin_Sw2)) return false;
|
||||
if(!write_std_vec_vec<double>(a_loc,"bin_Sxw",a_hdata.m_bin_Sxw)) return false;
|
||||
if(!write_std_vec_vec<double>(a_loc,"bin_Sx2w",a_hdata.m_bin_Sx2w)) return false;
|
||||
|
||||
// axes :
|
||||
{std::string name,saxis;
|
||||
for(unsigned int iaxis=0;iaxis<a_hdata.m_dimension;iaxis++) {
|
||||
tools::num2s(iaxis,saxis);
|
||||
name = "axis_"+saxis+"_";
|
||||
const histo_data_t::axis_t& _axis = a_hdata.m_axes[iaxis];
|
||||
if(!write_scalar<unsigned int>(a_loc,name+"offset",_axis.m_offset)) return false;
|
||||
if(!write_scalar<unsigned int>(a_loc,name+"number_of_bins",_axis.m_number_of_bins)) return false;
|
||||
if(!write_scalar<double>(a_loc,name+"minimum_value",_axis.m_minimum_value)) return false;
|
||||
if(!write_scalar<double>(a_loc,name+"maximum_value",_axis.m_maximum_value)) return false;
|
||||
if(!write_scalar<bool>(a_loc,name+"fixed",_axis.m_fixed)) return false;
|
||||
if(!write_scalar<double>(a_loc,name+"bin_width",_axis.m_bin_width)) return false;
|
||||
if(!write_std_vec<double>(a_loc,name+"edges",_axis.m_edges)) return false;
|
||||
}}
|
||||
|
||||
// etc :
|
||||
if(!write_std_vec<double>(a_loc,"in_range_plane_Sxyw",a_hdata.m_in_range_plane_Sxyw)) return false;
|
||||
|
||||
// m_annotations :
|
||||
if(!write_std_map_ss(a_loc,"annotations",a_hdata.m_annotations)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class HISTO>
|
||||
inline bool write_histo(std::ostream& a_out,hid_t a_loc,const std::string& a_name,const HISTO& a_histo) {
|
||||
|
||||
hid_t histo = tools_H5Gcreate(a_loc,a_name.c_str(),0);
|
||||
if(histo<0) {
|
||||
a_out << "tools::hdf5::write_histo : can't create group for histo " << tools::sout(a_name) << "." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!write_atb(histo,"type","object")) {
|
||||
a_out << "tools::hdf5::write_histo : write_atb() class failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
if(!write_atb(histo,"class",a_histo.s_cls())) {
|
||||
a_out << "tools::hdf5::write_histo : write_atb() class failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
int v = 1;
|
||||
if(!write_scalar_atb<int>(histo,"version",v)) {
|
||||
a_out << "tools::hdf5::write_histo : write_scalar_atb() version failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!write_hdata(histo,a_histo.dac())) {::H5Gclose(histo);return false;}
|
||||
|
||||
::H5Gclose(histo);
|
||||
|
||||
a_histo.not_a_profile(); //trick to be sure to use this function on an histo and not a profile.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class PROFILE>
|
||||
inline bool write_profile(std::ostream& a_out,hid_t a_loc,const std::string& a_name,const PROFILE& a_histo) {
|
||||
|
||||
hid_t histo = tools_H5Gcreate(a_loc,a_name.c_str(),0);
|
||||
if(histo<0) {
|
||||
a_out << "tools::hdf5::write_profile : can't create group for histo " << tools::sout(a_name) << "." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!write_atb(histo,"type","object")) {
|
||||
a_out << "tools::hdf5::write_profile : write_atb() class failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
if(!write_atb(histo,"class",a_histo.s_cls())) {
|
||||
a_out << "tools::hdf5::write_profile : write_atb() class failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
int v = 1;
|
||||
if(!write_scalar_atb<int>(histo,"version",v)) {
|
||||
a_out << "tools::hdf5::write_profile : write_scalar_atb() version failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
typename PROFILE::pd_t pdata = a_histo.get_histo_data();
|
||||
|
||||
if(!write_hdata(histo,pdata)) {::H5Gclose(histo);return false;}
|
||||
|
||||
if(!write_bool(histo,"is_profile",pdata.m_is_profile)) {::H5Gclose(histo);return false;}
|
||||
if(!write_std_vec<double>(histo,"bin_Svw",pdata.m_bin_Svw)) {::H5Gclose(histo);return false;}
|
||||
if(!write_std_vec<double>(histo,"bin_Sv2w",pdata.m_bin_Sv2w)) {::H5Gclose(histo);return false;}
|
||||
if(!write_bool(histo,"cut_v",pdata.m_cut_v)) {::H5Gclose(histo);return false;}
|
||||
if(!write_scalar<double>(histo,"min_v",pdata.m_min_v)) {::H5Gclose(histo);return false;}
|
||||
if(!write_scalar<double>(histo,"max_v",pdata.m_max_v)) {::H5Gclose(histo);return false;}
|
||||
|
||||
::H5Gclose(histo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_hdata(hid_t a_loc,histo_data_t& a_hdata) {
|
||||
if(!read_string(a_loc,"title",a_hdata.m_title)) return false;
|
||||
if(!read_scalar<unsigned int>(a_loc,"dimension",a_hdata.m_dimension)) return false;
|
||||
if(!read_scalar<unsigned int>(a_loc,"bin_number",a_hdata.m_bin_number)) return false;
|
||||
|
||||
if(!read_std_vec<unsigned int>(a_loc,"bin_entries",a_hdata.m_bin_entries)) return false;
|
||||
if(!read_std_vec<double>(a_loc,"bin_Sw",a_hdata.m_bin_Sw)) return false;
|
||||
if(!read_std_vec<double>(a_loc,"bin_Sw2",a_hdata.m_bin_Sw2)) return false;
|
||||
|
||||
if(!read_std_vec_vec<double>(a_loc,"bin_Sxw",a_hdata.m_bin_Sxw)) return false;
|
||||
if(!read_std_vec_vec<double>(a_loc,"bin_Sx2w",a_hdata.m_bin_Sx2w)) return false;
|
||||
|
||||
// axes :
|
||||
{a_hdata.m_axes.resize(a_hdata.m_dimension);
|
||||
std::string name,saxis;
|
||||
for(unsigned int iaxis=0;iaxis<a_hdata.m_dimension;iaxis++) {
|
||||
tools::num2s(iaxis,saxis);
|
||||
name = "axis_"+saxis+"_";
|
||||
histo_data_t::axis_t& _axis = a_hdata.m_axes[iaxis];
|
||||
if(!read_scalar<unsigned int>(a_loc,name+"offset",_axis.m_offset)) return false;
|
||||
if(!read_scalar<unsigned int>(a_loc,name+"number_of_bins",_axis.m_number_of_bins)) return false;
|
||||
if(!read_scalar<double>(a_loc,name+"minimum_value",_axis.m_minimum_value)) return false;
|
||||
if(!read_scalar<double>(a_loc,name+"maximum_value",_axis.m_maximum_value)) return false;
|
||||
if(!read_scalar<bool>(a_loc,name+"fixed",_axis.m_fixed)) return false;
|
||||
if(!read_scalar<double>(a_loc,name+"bin_width",_axis.m_bin_width)) return false;
|
||||
if(!read_std_vec<double>(a_loc,name+"edges",_axis.m_edges)) return false;
|
||||
}}
|
||||
|
||||
// etc :
|
||||
if(!read_std_vec<double>(a_loc,"in_range_plane_Sxyw",a_hdata.m_in_range_plane_Sxyw)) return false;
|
||||
|
||||
// m_annotations :
|
||||
if(!read_std_map_ss(a_loc,"annotations",a_hdata.m_annotations)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class HISTO>
|
||||
inline bool read_histo(std::ostream& a_out,hid_t a_loc,const std::string& a_name,HISTO*& a_histo) {
|
||||
a_histo = 0;
|
||||
|
||||
hid_t histo = tools_H5Gopen(a_loc,a_name.c_str());
|
||||
if(histo<0) {
|
||||
a_out << "tools::hdf5::read_histo : can't open group." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string sclass;
|
||||
if(!read_atb(histo,"class",sclass)) {
|
||||
a_out << "tools::hdf5::read_histo : can't read_atb() class." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sclass!=HISTO::s_class()) {
|
||||
a_out << "tools::hdf5::read_histo : unknown class : " << sclass << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
int v;
|
||||
if(!read_atb(histo,"version",v)) {
|
||||
a_out << "tools::hdf5::read_histo : read_atb version failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
histo_data_t hdata;
|
||||
|
||||
if(!read_hdata(histo,hdata)) {::H5Gclose(histo);return false;}
|
||||
|
||||
::H5Gclose(histo);
|
||||
|
||||
hdata.update_fast_getters();
|
||||
|
||||
a_histo = new HISTO;
|
||||
a_histo->copy_from_data(hdata);
|
||||
a_histo->not_a_profile(); //trick to be sure to use this function on an histo and not a profile.
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class PROFILE>
|
||||
inline bool read_profile(std::ostream& a_out,hid_t a_loc,const std::string& a_name,PROFILE*& a_histo) {
|
||||
a_histo = 0;
|
||||
|
||||
hid_t histo = tools_H5Gopen(a_loc,a_name.c_str());
|
||||
if(histo<0) {
|
||||
a_out << "tools::hdf5::read_profile : can't open group." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string sclass;
|
||||
if(!read_atb(histo,"class",sclass)) {
|
||||
a_out << "tools::hdf5::read_profile : can't read_atb() class." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sclass!=PROFILE::s_class()) {
|
||||
a_out << "tools::hdf5::read_profile : unknown class : " << sclass << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
int v;
|
||||
if(!read_atb(histo,"version",v)) {
|
||||
a_out << "tools::hdf5::read_profile : read_atb version failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
typename PROFILE::pd_t pdata;
|
||||
|
||||
if(!read_hdata(histo,pdata)) {::H5Gclose(histo);return false;}
|
||||
|
||||
if(!read_bool(histo,"is_profile",pdata.m_is_profile)) {::H5Gclose(histo);return false;}
|
||||
if(!read_std_vec<double>(histo,"bin_Svw",pdata.m_bin_Svw)) {::H5Gclose(histo);return false;}
|
||||
if(!read_std_vec<double>(histo,"bin_Sv2w",pdata.m_bin_Sv2w)) {::H5Gclose(histo);return false;}
|
||||
if(!read_bool(histo,"cut_v",pdata.m_cut_v)) {::H5Gclose(histo);return false;}
|
||||
if(!read_scalar<double>(histo,"min_v",pdata.m_min_v)) {::H5Gclose(histo);return false;}
|
||||
if(!read_scalar<double>(histo,"max_v",pdata.m_max_v)) {::H5Gclose(histo);return false;}
|
||||
|
||||
::H5Gclose(histo);
|
||||
|
||||
pdata.update_fast_getters();
|
||||
|
||||
a_histo = new PROFILE;
|
||||
a_histo->copy_from_data(pdata);
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_h
|
||||
#define tools_hdf5_h
|
||||
|
||||
#ifndef TOOLS_USE_OUREX_HDF5
|
||||
#include <hdf5.h>
|
||||
#else
|
||||
#include <ourex_hdf5.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if (H5_VERS_MAJOR>=1) && (H5_VERS_MINOR<=6)
|
||||
#define tools_H5Dopen H5Dopen
|
||||
#define tools_H5Dcreate H5Dcreate
|
||||
#define tools_H5Acreate H5Acreate
|
||||
#define tools_H5Tarray_create H5Tarray_create
|
||||
#define tools_H5Tget_array_dims H5Tget_array_dims
|
||||
#define tools_H5Gcreate H5Gcreate
|
||||
#define tools_H5Gopen H5Gopen
|
||||
#define tools_H5Aiterate H5Aiterate
|
||||
#else
|
||||
#define tools_H5Dopen H5Dopen1
|
||||
#define tools_H5Dcreate H5Dcreate1
|
||||
#define tools_H5Acreate H5Acreate1
|
||||
#define tools_H5Tarray_create H5Tarray_create1
|
||||
#define tools_H5Tget_array_dims H5Tget_array_dims1
|
||||
#define tools_H5Gcreate H5Gcreate1
|
||||
#define tools_H5Gopen H5Gopen1
|
||||
#define tools_H5Aiterate H5Aiterate1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_header
|
||||
#define tools_hdf5_header
|
||||
|
||||
#include "tools"
|
||||
#include "T_tools"
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool write_header(hid_t a_file,int a_version = 1) {
|
||||
hid_t header = tools_H5Gcreate(a_file,"header",0);
|
||||
if(header<0) return false;
|
||||
if(!write_atb(header,"writer","exlib")) {::H5Gclose(header);return false;}
|
||||
if(!write_scalar_atb<int>(header,"data_schema_version",a_version)) {::H5Gclose(header);return false;}
|
||||
::H5Gclose(header);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_header(hid_t a_file,std::string& a_writer,int& a_data_schema_version) {
|
||||
hid_t header = tools_H5Gopen(a_file,"header");
|
||||
if(header<0) {a_writer.clear();a_data_schema_version=0;return false;}
|
||||
if(!read_atb(header,"writer",a_writer)) {::H5Gclose(header);a_writer.clear();a_data_schema_version=0;return false;}
|
||||
if(!read_atb(header,"data_schema_version",a_data_schema_version)) {
|
||||
::H5Gclose(header);
|
||||
a_writer.clear();a_data_schema_version=0;
|
||||
return false;
|
||||
}
|
||||
::H5Gclose(header);
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,929 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_ntuple
|
||||
#define tools_hdf5_ntuple
|
||||
|
||||
#include "store"
|
||||
|
||||
#include <tools/vfind>
|
||||
#include <tools/vmanip>
|
||||
#include <tools/ntuple_binding>
|
||||
#include <tools/ntuple_booking>
|
||||
#include <tools/sout>
|
||||
#include <tools/scast>
|
||||
#include <tools/forit>
|
||||
#include <tools/stype>
|
||||
#include <tools/mnmx>
|
||||
#include <tools/vdata>
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
#include <tools/mem>
|
||||
#include <tools/stype>
|
||||
#endif
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
class ntuple : public store {
|
||||
public:
|
||||
class icol {
|
||||
public:
|
||||
virtual ~icol(){}
|
||||
public:
|
||||
virtual void* cast(tools::cid) const = 0;
|
||||
virtual tools::cid id_cls() const = 0;
|
||||
public:
|
||||
virtual bool set_basket_size(size_t a_size) = 0;
|
||||
virtual bool add() = 0;
|
||||
virtual bool fetch_entry() = 0;
|
||||
virtual const std::string& name() const = 0;
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
public:
|
||||
|
||||
template <class T>
|
||||
class column_ref : public virtual icol {
|
||||
#ifdef TOOLS_MEM
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::hdf5::ntuple::column_ref<"+tools::stype(T())+">");
|
||||
return s_v;
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
static tools::cid id_class() {
|
||||
static const T s_v = T(); //do that for T = std::string.
|
||||
return tools::_cid(s_v)+10000;
|
||||
}
|
||||
virtual void* cast(tools::cid a_class) const {
|
||||
if(void* p = tools::cmp_cast<column_ref>(this,a_class)) {return p;}
|
||||
else return 0;
|
||||
}
|
||||
virtual tools::cid id_cls() const {return id_class();}
|
||||
public: //icol
|
||||
virtual bool add() { //write.
|
||||
if(!m_write) return false;
|
||||
if(m_basket_pos>=m_basket_size) {
|
||||
if(!m_branch.write_page<T>(m_basket_size,m_basket)) {
|
||||
m_store.out() << "tools::hdf5::ntuple::column_ref::add : write_page() failed." << std::endl;
|
||||
m_basket_pos = 0;
|
||||
return false;
|
||||
}
|
||||
m_basket_pos = 0;
|
||||
if(m_want_new_basket_size) {
|
||||
delete [] m_basket;
|
||||
m_basket = new T[m_want_new_basket_size];
|
||||
m_basket_pos = 0;
|
||||
m_basket_size = m_want_new_basket_size;
|
||||
m_want_new_basket_size = 0;
|
||||
}
|
||||
}
|
||||
m_basket[m_basket_pos] = m_ref;
|
||||
m_basket_pos++;
|
||||
return true;
|
||||
}
|
||||
virtual bool fetch_entry() { //read.
|
||||
if(m_write) return false;
|
||||
if(m_basket_pos>=m_basket_end) { //we need more data.
|
||||
if(m_branch.pos()>=m_branch.entries()) {
|
||||
m_store.out() << "tools::hdf5::ntuple::column_ref:fetch_entry : no more data." << std::endl;
|
||||
m_basket_pos = 0;
|
||||
m_basket_end = 0;
|
||||
return false;
|
||||
}
|
||||
if(m_want_new_basket_size) {
|
||||
delete [] m_basket;
|
||||
m_basket = new T[m_want_new_basket_size];
|
||||
m_basket_pos = 0;
|
||||
m_basket_size = m_want_new_basket_size;
|
||||
m_want_new_basket_size = 0;
|
||||
}
|
||||
tools::uint64 remain = m_branch.entries()-m_branch.pos();
|
||||
size_t n = tools::mn<size_t>((size_t)remain,m_basket_size);
|
||||
if(!m_branch.read_page<T>(n,m_basket)) {
|
||||
m_store.out() << "tools::hdf5::ntuple::column_ref:fetch_entry : read_page() failed." << std::endl;
|
||||
m_basket_pos = 0;
|
||||
m_basket_end = 0;
|
||||
return false;
|
||||
}
|
||||
m_basket_pos = 0;
|
||||
m_basket_end = n;
|
||||
}
|
||||
m_ref = m_basket[m_basket_pos];
|
||||
m_basket_pos++;
|
||||
return true;
|
||||
}
|
||||
virtual void reset() {m_branch.reset_pos();}
|
||||
virtual const std::string& name() const {return m_name;}
|
||||
virtual bool set_basket_size(size_t a_size) {
|
||||
if(!a_size) return false;
|
||||
m_want_new_basket_size = a_size;
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
column_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size,T& a_ref)
|
||||
:m_store(a_store)
|
||||
,m_branch(a_pages)
|
||||
,m_write(a_write)
|
||||
,m_name(a_name)
|
||||
,m_ref(a_ref)
|
||||
,m_basket_size(a_basket_size?a_basket_size:32000)
|
||||
,m_basket_pos(0)
|
||||
,m_basket_end(0) //read.
|
||||
,m_basket(0)
|
||||
,m_want_new_basket_size(0)
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
m_basket = new T[m_basket_size];
|
||||
if(m_write) {
|
||||
} else { //read.
|
||||
size_t n = tools::mn<size_t>((size_t)m_branch.entries(),m_basket_size);
|
||||
if(!m_branch.read_page<T>(n,m_basket)) {
|
||||
m_store.out() << "tools::hdf5::ntuple::column_ref:column_ref : read_page() failed." << std::endl;
|
||||
m_basket_pos = 0;
|
||||
m_basket_end = 0;
|
||||
return;
|
||||
}
|
||||
m_basket_pos = 0;
|
||||
m_basket_end = n;
|
||||
}
|
||||
}
|
||||
virtual ~column_ref(){
|
||||
if(m_write && m_basket_pos) {
|
||||
if(!m_branch.write_page<T>(m_basket_pos,m_basket)) {
|
||||
m_store.out() << "tools::hdf5::ntuple::column_ref::~column_ref : write_page() failed." << std::endl;
|
||||
}
|
||||
}
|
||||
delete [] m_basket;
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected:
|
||||
column_ref(const column_ref& a_from)
|
||||
:icol(a_from)
|
||||
,m_store(a_from.m_store)
|
||||
,m_branch(a_from.m_branch)
|
||||
,m_write(a_from.m_write)
|
||||
,m_name(a_from.m_name)
|
||||
,m_ref(a_from.m_ref)
|
||||
,m_basket_size(a_from.m_basket_size)
|
||||
,m_basket_pos(0)
|
||||
,m_basket_end(0)
|
||||
,m_basket(0)
|
||||
,m_want_new_basket_size(0)
|
||||
{}
|
||||
column_ref& operator=(const column_ref& a_from){
|
||||
if(&a_from==this) return *this;
|
||||
m_name = a_from.m_name;
|
||||
m_basket_size = a_from.m_basket_size;
|
||||
m_basket_pos = 0;
|
||||
m_basket_end = 0;
|
||||
m_want_new_basket_size = 0;
|
||||
return *this;
|
||||
}
|
||||
protected:
|
||||
store& m_store;
|
||||
pages& m_branch;
|
||||
bool m_write;
|
||||
std::string m_name;
|
||||
T& m_ref;
|
||||
size_t m_basket_size;
|
||||
size_t m_basket_pos;
|
||||
size_t m_basket_end;
|
||||
T* m_basket;
|
||||
size_t m_want_new_basket_size;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class column : public column_ref<T> {
|
||||
typedef column_ref<T> parent;
|
||||
#ifdef TOOLS_MEM
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::hdf5::ntuple::column<"+tools::stype(T())+">");
|
||||
return s_v;
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
static tools::cid id_class() {
|
||||
static const T s_v = T(); //do that for T = std::string.
|
||||
return tools::_cid(s_v);
|
||||
}
|
||||
virtual void* cast(tools::cid a_class) const {
|
||||
if(void* p = tools::cmp_cast<column>(this,a_class)) {return p;}
|
||||
else return 0;
|
||||
}
|
||||
virtual tools::cid id_cls() const {return id_class();}
|
||||
public:
|
||||
column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size)
|
||||
:parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
|
||||
,m_tmp(T())
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
virtual ~column(){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected:
|
||||
column(const column& a_from)
|
||||
:icol(a_from)
|
||||
,parent(a_from)
|
||||
,m_tmp(a_from.m_tmp)
|
||||
{}
|
||||
column& operator=(const column& a_from){
|
||||
if(&a_from==this) return *this;
|
||||
parent::operator=(a_from);
|
||||
m_tmp = a_from.m_tmp;
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
bool fill(const T& a_value) {m_tmp = a_value;return true;} //write.
|
||||
bool get_entry(T& a_v) const {a_v = m_tmp;return true;} //read.
|
||||
protected:
|
||||
T m_tmp;
|
||||
};
|
||||
|
||||
TOOLS_CLASS_STRING_VALUE(vector_char,vector<char>)
|
||||
TOOLS_CLASS_STRING_VALUE(vector_short,vector<short>)
|
||||
TOOLS_CLASS_STRING_VALUE(vector_int,vector<int>)
|
||||
TOOLS_CLASS_STRING_VALUE(vector_float,vector<float>)
|
||||
TOOLS_CLASS_STRING_VALUE(vector_double,vector<double>)
|
||||
|
||||
TOOLS_CLASS_STRING_VALUE(string,string)
|
||||
|
||||
TOOLS_CLASS_STRING_VALUE(vector_int64,vector<tools::int64>)
|
||||
TOOLS_CLASS_STRING_VALUE(vector_uchar,vector<tools::uchar>)
|
||||
TOOLS_CLASS_STRING_VALUE(vector_ushort,vector<tools::ushort>)
|
||||
TOOLS_CLASS_STRING_VALUE(vector_uint32,vector<tools::uint32>)
|
||||
TOOLS_CLASS_STRING_VALUE(vector_uint64,vector<tools::uint64>)
|
||||
|
||||
template <class T>
|
||||
class std_vector_column_ref : public column<unsigned int> {
|
||||
typedef column<unsigned int> parent;
|
||||
#ifdef TOOLS_MEM
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::hdf5::ntuple::std_vector_column_ref<"+tools::stype(T())+">");
|
||||
return s_v;
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
static tools::cid id_class() {return tools::_cid_std_vector<T>()+10000;}
|
||||
virtual void* cast(tools::cid a_class) const {
|
||||
if(void* p = tools::cmp_cast<std_vector_column_ref>(this,a_class)) {return p;}
|
||||
else return 0;
|
||||
}
|
||||
virtual tools::cid id_cls() const {return id_class();}
|
||||
public: //icol
|
||||
virtual void reset() {
|
||||
m_branch.reset_pos();
|
||||
m_data_pages.reset_pos();
|
||||
}
|
||||
virtual bool add() { //write.
|
||||
if(!m_write) return false;
|
||||
if(m_ref.size()) {
|
||||
const T* _data = tools::vec_data(m_ref);
|
||||
if(!m_data_pages.write_page<T>(m_ref.size(),(void*)_data)) return false;
|
||||
}
|
||||
if(!parent::fill((unsigned int)m_ref.size())) return false;
|
||||
if(!parent::add()) return false;
|
||||
return true;
|
||||
}
|
||||
virtual bool fetch_entry() { //read.
|
||||
if(m_write) return false;
|
||||
if(!parent::fetch_entry()) return false;
|
||||
unsigned int sz;
|
||||
if(!parent::get_entry(sz)) return false;
|
||||
m_ref.resize(sz,T());
|
||||
if(sz) {
|
||||
T* _data = tools::vec_data(m_ref);
|
||||
if(!m_data_pages.read_page<T>(sz,_data)) {m_ref.clear();return false;}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual const std::string& name() const {return m_name;}
|
||||
virtual bool set_basket_size(size_t /*a_size*/) {
|
||||
//m_branch->set_basket_size(a_size);
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
std_vector_column_ref(store& a_store,pages& a_pages,bool a_write,
|
||||
const std::string& a_name,size_t a_basket_size,
|
||||
std::vector<T>& a_ref)
|
||||
:parent(a_store,a_pages,a_write,a_name,a_basket_size)
|
||||
,m_ref(a_ref)
|
||||
,m_data_pages(a_store.out(),a_store.group(),a_name+"_data",tools::stype(T()),a_write,a_store.compress_level())
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
if(!m_data_pages.is_valid()) {
|
||||
m_store.out() << "tools::hdf5::std_vector_column_ref::std_vector_column_ref :"
|
||||
<< " can't create data pages." << std::endl;
|
||||
}
|
||||
}
|
||||
virtual ~std_vector_column_ref(){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected:
|
||||
std_vector_column_ref(const std_vector_column_ref& a_from)
|
||||
:icol(a_from)
|
||||
,parent(a_from)
|
||||
,m_ref(a_from.m_ref)
|
||||
,m_data_pages(a_from.m_store.out(),a_from.m_store.group(),a_from.m_name+"_data",
|
||||
tools::stype(T()),a_from.m_write,a_from.m_store.compress_level())
|
||||
{}
|
||||
std_vector_column_ref& operator=(const std_vector_column_ref& a_from){
|
||||
if(&a_from==this) return *this;
|
||||
m_name = a_from.m_name;
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
//const std::vector<T>& ref() const {return m_ref;}
|
||||
protected:
|
||||
std::vector<T>& m_ref;
|
||||
pages m_data_pages;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class std_vector_column : public std_vector_column_ref<T> {
|
||||
typedef std_vector_column_ref<T> parent;
|
||||
#ifdef TOOLS_MEM
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::hdf5::ntuple::std_vector_column<"+tools::stype(T())+">");
|
||||
return s_v;
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
static tools::cid id_class() {return tools::_cid_std_vector<T>();}
|
||||
virtual void* cast(tools::cid a_class) const {
|
||||
if(void* p = tools::cmp_cast<std_vector_column>(this,a_class)) {return p;}
|
||||
else return 0;
|
||||
}
|
||||
virtual tools::cid id_cls() const {return id_class();}
|
||||
public:
|
||||
std_vector_column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size)
|
||||
:parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
|
||||
{}
|
||||
virtual ~std_vector_column(){}
|
||||
protected:
|
||||
std_vector_column(const std_vector_column& a_from)
|
||||
:icol(a_from)
|
||||
,parent(a_from)
|
||||
{}
|
||||
std_vector_column& operator=(const std_vector_column& a_from){
|
||||
parent::operator=(a_from);
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
//bool get_entry(std::vector<T>& a_v) const {
|
||||
// a_v = m_tmp;
|
||||
// return true;
|
||||
//}
|
||||
const std::vector<T>& data() const {return m_tmp;}
|
||||
protected:
|
||||
std::vector<T> m_tmp;
|
||||
};
|
||||
|
||||
class column_string_ref : public column<unsigned int> {
|
||||
typedef column<unsigned int> parent;
|
||||
#ifdef TOOLS_MEM
|
||||
TOOLS_SCLASS(tools::hdf5::ntuple::column_string_ref)
|
||||
#endif
|
||||
public:
|
||||
static tools::cid id_class() {
|
||||
static const std::string s_v;
|
||||
return tools::_cid(s_v)+10000;
|
||||
}
|
||||
virtual void* cast(tools::cid a_class) const {
|
||||
if(void* p = tools::cmp_cast<column_string_ref>(this,a_class)) {return p;}
|
||||
else return 0;
|
||||
}
|
||||
virtual tools::cid id_cls() const {return id_class();}
|
||||
public: //icol
|
||||
virtual void reset() {
|
||||
m_branch.reset_pos();
|
||||
m_data_pages.reset_pos();
|
||||
}
|
||||
virtual bool add() { //write.
|
||||
if(!m_write) return false;
|
||||
if(m_ref.size()) {
|
||||
const char* _data = m_ref.c_str();
|
||||
if(!m_data_pages.write_page<char>(m_ref.size(),(void*)_data)) return false;
|
||||
}
|
||||
if(!parent::fill((unsigned int)m_ref.size())) return false;
|
||||
if(!parent::add()) return false;
|
||||
return true;
|
||||
}
|
||||
virtual bool fetch_entry() { //read.
|
||||
if(m_write) return false;
|
||||
if(!parent::fetch_entry()) return false;
|
||||
unsigned int sz;
|
||||
if(!parent::get_entry(sz)) return false;
|
||||
m_ref.resize(sz);
|
||||
if(sz) {
|
||||
char* _data = (char*)m_ref.c_str();
|
||||
if(!m_data_pages.read_page<char>(sz,_data)) {m_ref.clear();return false;}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual const std::string& name() const {return m_name;}
|
||||
virtual bool set_basket_size(size_t /*a_size*/) {
|
||||
//m_branch->set_basket_size(a_size);
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
column_string_ref(store& a_store,pages& a_pages,bool a_write,
|
||||
const std::string& a_name,size_t a_basket_size,
|
||||
std::string& a_ref)
|
||||
:parent(a_store,a_pages,a_write,a_name,a_basket_size)
|
||||
,m_ref(a_ref)
|
||||
,m_data_pages(a_store.out(),a_store.group(),a_name+"_data",tools::stype(char()),a_write,a_store.compress_level())
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
if(!m_data_pages.is_valid()) {
|
||||
m_store.out() << "tools::hdf5::column_string_ref::column_string_ref :"
|
||||
<< " can't create data pages." << std::endl;
|
||||
}
|
||||
}
|
||||
virtual ~column_string_ref(){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected:
|
||||
column_string_ref(const column_string_ref& a_from)
|
||||
:icol(a_from)
|
||||
,parent(a_from)
|
||||
,m_ref(a_from.m_ref)
|
||||
,m_data_pages(a_from.m_store.out(),a_from.m_store.group(),a_from.m_name+"_data",
|
||||
tools::stype(char()),a_from.m_write,a_from.m_store.compress_level())
|
||||
{}
|
||||
column_string_ref& operator=(const column_string_ref& a_from){
|
||||
if(&a_from==this) return *this;
|
||||
m_name = a_from.m_name;
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
//const std::string& ref() const {return m_ref;}
|
||||
protected:
|
||||
std::string& m_ref;
|
||||
pages m_data_pages;
|
||||
};
|
||||
|
||||
class column_string : public column_string_ref {
|
||||
typedef column_string_ref parent;
|
||||
#ifdef TOOLS_MEM
|
||||
TOOLS_SCLASS(tools::hdf5::ntuple::column_string)
|
||||
#endif
|
||||
public:
|
||||
static tools::cid id_class() {
|
||||
static const std::string s_v;
|
||||
return tools::_cid(s_v);
|
||||
}
|
||||
virtual void* cast(tools::cid a_class) const {
|
||||
if(void* p = tools::cmp_cast<column_string>(this,a_class)) {return p;}
|
||||
else return 0;
|
||||
}
|
||||
virtual tools::cid id_cls() const {return id_class();}
|
||||
public:
|
||||
column_string(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,tools::uint32 a_basket_size)
|
||||
:parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
virtual ~column_string(){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected:
|
||||
column_string(const column_string& a_from)
|
||||
:icol(a_from)
|
||||
,parent(a_from)
|
||||
{}
|
||||
column_string& operator=(const column_string& a_from){
|
||||
if(&a_from==this) return *this;
|
||||
parent::operator=(a_from);
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
bool fill(const std::string& a_value) {m_tmp = a_value;return true;}
|
||||
bool get_entry(std::string& a_value) const {a_value = m_tmp;return true;}
|
||||
protected:
|
||||
std::string m_tmp;
|
||||
};
|
||||
|
||||
public:
|
||||
ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name,
|
||||
unsigned int a_compress,size_t /*a_basket_size*//* = 32000*/)
|
||||
:store(a_out,a_group,a_name,true,a_compress) //true=write
|
||||
{}
|
||||
|
||||
ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name)
|
||||
:store(a_out,a_group,a_name,false,0) //false=read
|
||||
{
|
||||
tools_vforcit(pages*,m_pagess,it){
|
||||
|
||||
#define TOOLS_HDF5_NTUPLE_READ_CREATE_COL(a__type) \
|
||||
if((*it)->form()==tools::stype(a__type())) {\
|
||||
column<a__type>* col = new column<a__type>(*this,*(*it),false,(*it)->name(),0);\
|
||||
if(!col) {tools::safe_clear<icol>(m_cols);return;}\
|
||||
m_cols.push_back(col);\
|
||||
}
|
||||
|
||||
#define TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(a__vec_type,a__type) \
|
||||
if((*it)->form()==s_vector_##a__vec_type()) {\
|
||||
std_vector_column<a__type>* col = new std_vector_column<a__type>(*this,*(*it),false,(*it)->name(),0);\
|
||||
if(!col) {tools::safe_clear<icol>(m_cols);return;}\
|
||||
m_cols.push_back(col);\
|
||||
}
|
||||
|
||||
TOOLS_HDF5_NTUPLE_READ_CREATE_COL(char)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(short)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(int)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(tools::int64)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(float)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(double)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(tools::byte)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(tools::ushort)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(tools::uint32)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(tools::uint64)
|
||||
|
||||
//else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(bool) //use byte=uchar.
|
||||
|
||||
else
|
||||
if((*it)->form()==s_string()) {
|
||||
column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0);
|
||||
if(!col) {tools::safe_clear<icol>(m_cols);return;}
|
||||
m_cols.push_back(col);
|
||||
}
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(char,char)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(short,short)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(int,int)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(int64,tools::int64)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(float,float)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(double,double)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(uchar,tools::uchar)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(ushort,tools::ushort)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint32,tools::uint32)
|
||||
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint64,tools::uint64)
|
||||
|
||||
// else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(std::string)
|
||||
// else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(bool) //use byte=uchar.
|
||||
|
||||
else {
|
||||
m_out << "tools::hdf5::ntuple::ntuple(read) :"
|
||||
<< " for column " << tools::sout((*it)->name())
|
||||
<< ", type " << tools::sout((*it)->form()) << " not yet handled."
|
||||
<< std::endl;
|
||||
//throw
|
||||
tools::safe_clear<icol>(m_cols);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#undef TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL
|
||||
#undef TOOLS_HDF5_NTUPLE_READ_CREATE_COL
|
||||
}
|
||||
|
||||
ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name,const tools::ntuple_binding& a_bd)
|
||||
:store(a_out,a_group,a_name,false,0) //false=read
|
||||
{
|
||||
if(!initialize(a_out,a_bd)) {}
|
||||
}
|
||||
|
||||
ntuple(std::ostream& a_out,hid_t a_group,const tools::ntuple_booking& a_bkg,
|
||||
unsigned int a_compress,size_t a_basket_size/* = 32000*/)
|
||||
:store(a_out,a_group,a_bkg.name(),true,a_compress) //true=write
|
||||
,m_title(a_bkg.title())
|
||||
{
|
||||
const std::vector<tools::column_booking>& cols = a_bkg.columns();
|
||||
tools_vforcit(tools::column_booking,cols,it){
|
||||
|
||||
#define TOOLS_HDF5_NTUPLE_CREATE_COL(a__type) \
|
||||
if((*it).cls_id()==tools::_cid(a__type())) {\
|
||||
a__type* user = (a__type*)(*it).user_obj();\
|
||||
if(user) {\
|
||||
if(!create_column_ref<a__type>((*it).name(),a_basket_size,*user)) {\
|
||||
m_out << "tools::hdf5::ntuple :"\
|
||||
<< " can't create column_ref " << tools::sout((*it).name()) << "."\
|
||||
<< std::endl;\
|
||||
tools::safe_clear<icol>(m_cols);\
|
||||
return;\
|
||||
}\
|
||||
} else {\
|
||||
if(!create_column<a__type>((*it).name(),a_basket_size)) {\
|
||||
m_out << "tools::hdf5::ntuple :"\
|
||||
<< " can't create column " << tools::sout((*it).name()) << "."\
|
||||
<< std::endl;\
|
||||
tools::safe_clear<icol>(m_cols);\
|
||||
return;\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
#define TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(a__type) \
|
||||
if((*it).cls_id()==tools::_cid_std_vector<a__type>()) {\
|
||||
std::vector<a__type>* vec = (std::vector<a__type>*)(*it).user_obj();\
|
||||
if(!vec) {\
|
||||
m_out << "tools::hdf5::ntuple :"\
|
||||
<< " for std::vector column " << tools::sout((*it).name())\
|
||||
<< ", the user vector pointer is null."\
|
||||
<< std::endl;\
|
||||
tools::safe_clear<icol>(m_cols);\
|
||||
return;\
|
||||
}\
|
||||
if(!create_std_column_ref<a__type>((*it).name(),a_basket_size,*vec)) {\
|
||||
m_out << "tools::hdf5::ntuple :"\
|
||||
<< " can't create std::vector column " << tools::sout((*it).name()) << "."\
|
||||
<< std::endl;\
|
||||
tools::safe_clear<icol>(m_cols);\
|
||||
return;\
|
||||
}\
|
||||
}
|
||||
|
||||
TOOLS_HDF5_NTUPLE_CREATE_COL(char)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_COL(short)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_COL(int)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_COL(tools::int64)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_COL(float)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_COL(double)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_COL(tools::byte)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_COL(tools::ushort)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_COL(tools::uint32)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_COL(tools::uint64)
|
||||
|
||||
//else TOOLS_HDF5_NTUPLE_CREATE_COL(bool) //use byte=uchar.
|
||||
|
||||
else if((*it).cls_id()==tools::_cid(std::string())) {
|
||||
if(!create_column_string((*it).name(),a_basket_size)) {
|
||||
m_out << "tools::hdf5::ntuple :"
|
||||
<< " can't create string column " << tools::sout((*it).name()) << "."
|
||||
<< std::endl;
|
||||
tools::safe_clear<icol>(m_cols);
|
||||
return;
|
||||
}
|
||||
|
||||
} else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(char)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(short)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(int)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(tools::int64)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(float)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(double)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(tools::uchar)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(tools::ushort)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint32)
|
||||
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint64)
|
||||
|
||||
// else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(std::string)
|
||||
// else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(bool) //use byte=uchar.
|
||||
|
||||
else {
|
||||
m_out << "tools::hdf5::ntuple :"
|
||||
<< " for column " << tools::sout((*it).name())
|
||||
<< ", type with cid " << (*it).cls_id() << " not yet handled."
|
||||
<< std::endl;
|
||||
tools::safe_clear<icol>(m_cols);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#undef TOOLS_HDF5_NTUPLE_CREATE_COL
|
||||
#undef TOOLS_HDF5_NTUPLE_CREATE_VEC_COL
|
||||
|
||||
}
|
||||
|
||||
virtual ~ntuple() {
|
||||
tools::safe_clear<icol>(m_cols);
|
||||
}
|
||||
protected:
|
||||
ntuple(const ntuple& a_from):store(a_from),m_title(a_from.m_title){}
|
||||
ntuple& operator=(const ntuple&){return *this;}
|
||||
public:
|
||||
bool initialize(std::ostream& a_out,const tools::ntuple_binding& a_bd = tools::ntuple_binding()) {
|
||||
tools::safe_clear<icol>(m_cols);
|
||||
{tools_vforcit(pages*,m_pagess,it) (*it)->reset_pos();}
|
||||
|
||||
tools_vforcit(pages*,m_pagess,it) {
|
||||
|
||||
#define TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(a__type) \
|
||||
if((*it)->form()==tools::stype(a__type())) {\
|
||||
a__type* user_var = a_bd.find_variable<a__type>((*it)->name());\
|
||||
if(user_var) {\
|
||||
column_ref<a__type>* col = new column_ref<a__type>(*this,*(*it),false,(*it)->name(),0,*user_var);\
|
||||
if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
|
||||
m_cols.push_back(col);\
|
||||
} else {\
|
||||
column<a__type>* col = new column<a__type>(*this,*(*it),false,(*it)->name(),0);\
|
||||
if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
|
||||
m_cols.push_back(col);\
|
||||
}\
|
||||
}
|
||||
|
||||
#define TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(a__vec_type,a__type) \
|
||||
if((*it)->form()==s_vector_##a__vec_type()) {\
|
||||
std::vector<a__type>* user_var = a_bd.find_variable< std::vector<a__type> >((*it)->name());\
|
||||
if(user_var) {\
|
||||
std_vector_column_ref<a__type>* col = \
|
||||
new std_vector_column_ref<a__type>(*this,*(*it),false,(*it)->name(),0,*user_var);\
|
||||
if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
|
||||
m_cols.push_back(col);\
|
||||
} else {\
|
||||
std_vector_column<a__type>* col = new std_vector_column<a__type>(*this,*(*it),false,(*it)->name(),0);\
|
||||
if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
|
||||
m_cols.push_back(col);\
|
||||
}\
|
||||
}
|
||||
|
||||
TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(char)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(short)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(int)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::int64)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(float)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(double)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::byte)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::ushort)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint32)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint64)
|
||||
|
||||
//else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(bool) //use byte=uchar.
|
||||
|
||||
else
|
||||
if((*it)->form()==s_string()) {
|
||||
std::string* user_var = a_bd.find_variable<std::string>((*it)->name());
|
||||
if(user_var) {
|
||||
column_string_ref* col = new column_string_ref(*this,*(*it),false,(*it)->name(),0,*user_var);
|
||||
if(!col) {tools::safe_clear<icol>(m_cols);return false;}
|
||||
m_cols.push_back(col);
|
||||
} else {
|
||||
column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0);
|
||||
if(!col) {tools::safe_clear<icol>(m_cols);return false;}
|
||||
m_cols.push_back(col);
|
||||
}
|
||||
}
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(char,char)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(short,short)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int,int)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int64,tools::int64)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(float,float)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(double,double)
|
||||
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uchar,tools::uchar)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(ushort,tools::ushort)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint32,tools::uint32)
|
||||
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint64,tools::uint64)
|
||||
|
||||
// else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(std::string)
|
||||
// else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(bool) //use byte=uchar.
|
||||
|
||||
else {
|
||||
a_out << "tools::hdf5::ntuple::ntuple(read with binding) :"
|
||||
<< " for column " << tools::sout((*it)->name())
|
||||
<< ", type " << tools::sout((*it)->form()) << " not yet handled."
|
||||
<< std::endl;
|
||||
tools::safe_clear<icol>(m_cols);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#undef TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL
|
||||
#undef TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::vector<icol*>& columns() const {return m_cols;}
|
||||
std::vector<icol*>& columns() {return m_cols;}
|
||||
|
||||
template <class T>
|
||||
column_ref<T>* create_column_ref(const std::string& a_name,size_t a_basket_size,T& a_user_var) {
|
||||
if(tools::find_named<icol>(m_cols,a_name)) return 0;
|
||||
pages* _pages = create_pages(a_name,tools::stype(T()));
|
||||
if(!_pages) return 0;
|
||||
column_ref<T>* col = new column_ref<T>(*this,*_pages,true,a_name,a_basket_size,a_user_var);
|
||||
if(!col) return 0;
|
||||
m_cols.push_back(col);
|
||||
return col;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
column<T>* create_column(const std::string& a_name,size_t a_basket_size) {
|
||||
if(tools::find_named<icol>(m_cols,a_name)) return 0;
|
||||
pages* _pages = create_pages(a_name,tools::stype(T()));
|
||||
if(!_pages) return 0;
|
||||
column<T>* col = new column<T>(*this,*_pages,true,a_name,a_basket_size);
|
||||
if(!col) return 0;
|
||||
m_cols.push_back(col);
|
||||
return col;
|
||||
}
|
||||
|
||||
column_string* create_column_string(const std::string& a_name,size_t a_basket_size) {
|
||||
if(tools::find_named<icol>(m_cols,a_name)) return 0;
|
||||
pages* _pages = create_pages(a_name,s_string());
|
||||
if(!_pages) return 0;
|
||||
column_string* col = new column_string(*this,*_pages,true,a_name,a_basket_size);
|
||||
if(!col) return 0;
|
||||
m_cols.push_back(col);
|
||||
return col;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std_vector_column_ref<T>* create_std_column_ref(const std::string& a_name,size_t a_basket_size,std::vector<T>& a_user_vec) {
|
||||
//NOTE : to optimize, we do not handle a default std::vector value logic.
|
||||
if(tools::find_named<icol>(m_cols,a_name)) return 0;
|
||||
pages* _pages = create_pages(a_name,"vector<"+tools::stype(T())+">");
|
||||
if(!_pages) return 0;
|
||||
std_vector_column_ref<T>* col = new std_vector_column_ref<T>(*this,*_pages,true,a_name,a_basket_size,a_user_vec);
|
||||
if(!col) return 0;
|
||||
m_cols.push_back(col);
|
||||
return col;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
column_ref<T>* find_column_ref(const std::string& a_name) {
|
||||
icol* col = tools::find_named<icol>(m_cols,a_name);
|
||||
if(!col) return 0;
|
||||
return tools::id_cast<icol, column_ref<T> >(*col);
|
||||
}
|
||||
template <class T>
|
||||
column<T>* find_column(const std::string& a_name) {
|
||||
icol* col = tools::find_named<icol>(m_cols,a_name);
|
||||
if(!col) return 0;
|
||||
return tools::id_cast<icol, column<T> >(*col);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std_vector_column_ref<T>* find_std_vector_column_ref(const std::string& a_name) {
|
||||
icol* col = tools::find_named<icol>(m_cols,a_name);
|
||||
if(!col) return 0;
|
||||
return tools::id_cast<icol, std_vector_column_ref<T> >(*col);
|
||||
}
|
||||
template <class T>
|
||||
std_vector_column<T>* find_std_vector_column(const std::string& a_name) {
|
||||
icol* col = tools::find_named<icol>(m_cols,a_name);
|
||||
if(!col) return 0;
|
||||
return tools::id_cast<icol, std_vector_column<T> >(*col);
|
||||
}
|
||||
|
||||
column_string* find_column_string(const std::string& a_name) {
|
||||
icol* col = tools::find_named<icol>(m_cols,a_name);
|
||||
if(!col) return 0;
|
||||
return tools::id_cast<icol, column_string >(*col);
|
||||
}
|
||||
|
||||
bool add_row() { //write.
|
||||
if(m_cols.empty()) return false;
|
||||
bool status = true;
|
||||
tools_vforit(icol*,m_cols,it) {if(!(*it)->add()) status = false;}
|
||||
//tools::uint32 n;
|
||||
//bool status = store::fill(n);
|
||||
//tools_vforit(icol*,m_cols,it) (*it)->set_def();
|
||||
return status;
|
||||
}
|
||||
|
||||
bool get_row() { //read.
|
||||
bool status = true;
|
||||
tools_vforcit(icol*,m_cols,it) {
|
||||
if(!(*it)->fetch_entry()) status = false;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
bool set_basket_size(size_t a_size) {
|
||||
tools_vforit(icol*,m_cols,it) {if(!(*it)->set_basket_size(a_size)) return false;}
|
||||
return true;
|
||||
}
|
||||
|
||||
void reset() { //read.
|
||||
tools_vforit(icol*,m_cols,it) (*it)->reset();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string m_title;
|
||||
std::vector<icol*> m_cols;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,234 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_pages
|
||||
#define tools_hdf5_pages
|
||||
|
||||
#include "T_tools"
|
||||
#include "tools"
|
||||
|
||||
#include <tools/S_STRING>
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
#include <tools/mem>
|
||||
#endif
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
TOOLS_GLOBAL_STRING(pages)
|
||||
TOOLS_GLOBAL_STRING(entries)
|
||||
TOOLS_GLOBAL_STRING(columns)
|
||||
TOOLS_GLOBAL_STRING(names)
|
||||
TOOLS_GLOBAL_STRING(forms)
|
||||
|
||||
class pages {
|
||||
TOOLS_SCLASS(tools::hdf5::pages)
|
||||
public:
|
||||
pages(std::ostream& a_out,
|
||||
hid_t a_group,const std::string& a_name,const std::string& a_form,
|
||||
bool a_write,unsigned int a_compress)
|
||||
:m_out(a_out),m_name(a_name),m_form(a_form)
|
||||
//,m_type(0),m_size(0)
|
||||
,m_group(-1),m_dataset(-1),m_write(a_write),m_compress(a_compress),m_entries(0),m_pos(0){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
if(m_write) {
|
||||
m_group = tools_H5Gcreate(a_group,m_name.c_str(),0);
|
||||
if(m_group<0) {
|
||||
m_out << "pages::pages : can't create group for column " << m_name << "." << std::endl;
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
if(!write_atb(m_group,"class",s_class())) {
|
||||
m_out << "pages::pages : write_atb(class) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
int v = 1;
|
||||
if (!write_scalar_atb<int>(m_group,"version",v)) {
|
||||
m_out << "pages::pages : write_scalar_atb(version) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
m_group = tools_H5Gopen(a_group,m_name.c_str());
|
||||
if(m_group<0) {
|
||||
m_out << "pages::pages : can't open group for column " << m_name << "." << std::endl;
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
if(!read_scalar<tools::uint64>(m_group,s_entries(),m_entries)) {
|
||||
m_out << "pages::pages : read_scalar(entries) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual ~pages(){
|
||||
if(m_write) {
|
||||
if(!write_scalar<tools::uint64>(m_group,s_entries(),m_entries)) {
|
||||
m_out << "pages::~pages : write_scalar(entries) failed." << std::endl;
|
||||
}
|
||||
if(m_dataset>=0) ::H5Dclose(m_dataset);
|
||||
}
|
||||
::H5Gclose(m_group);
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected:
|
||||
pages(const pages& a_from):m_out(a_from.m_out){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
pages& operator=(const pages&){return *this;}
|
||||
public:
|
||||
bool is_valid() const {return m_group<0?false:true;}
|
||||
|
||||
const std::string& name() const {return m_name;}
|
||||
const std::string& form() const {return m_form;}
|
||||
//int type() const {return m_type;}
|
||||
//unsigned int size() const {return m_size;}
|
||||
tools::uint64 entries() const {return m_entries;}
|
||||
tools::uint64 pos() const {return m_pos;}
|
||||
void reset_pos() {m_pos = 0;}
|
||||
|
||||
template <class TYPE>
|
||||
bool write_page(size_t a_size,void* a_array) {
|
||||
if(!m_pos) {
|
||||
if(!write_array<TYPE>(m_group,s_pages(),a_size,(TYPE*)a_array,a_size,m_compress)) {
|
||||
m_out << "pages::write_page : write_array<TYPE>() failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
m_dataset = tools_H5Dopen(m_group,s_pages().c_str());
|
||||
if(m_dataset<0) {
|
||||
m_out << "pages::write_page : H5Dopen failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(!write_append_array_dataset<TYPE>(m_dataset,a_size,(TYPE*)a_array)) {
|
||||
m_out << "pages::write_page : write_append_array<TYPE>() failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_pos += a_size;
|
||||
m_entries = m_pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
bool read_page(size_t a_size,void* a_array) {
|
||||
//it is assumed that a_array can contain a_size*sizeof(TYPE) bytes.
|
||||
unsigned int _size = a_size;
|
||||
unsigned int n = 0;
|
||||
TYPE* array = 0;
|
||||
if(!read_sub_array<TYPE>(m_group,s_pages(),(unsigned int)m_pos,(unsigned int)_size,n,array)) {
|
||||
m_out << "pages::read_page : read_sub_array<TYPE>() failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(n!=_size) {
|
||||
m_out << "pages::read_page : size mismatch. Requested " << _size << ", got "<< n << "." << std::endl;
|
||||
delete [] array;
|
||||
return false;
|
||||
}
|
||||
|
||||
{TYPE* rpos = (TYPE*)array;
|
||||
TYPE* wpos = (TYPE*)a_array;
|
||||
for(size_t i=0;i<n;i++,rpos++,wpos++) *wpos = *rpos;
|
||||
for(size_t i=n;i<_size;i++,rpos++,wpos++) *wpos = TYPE();}
|
||||
|
||||
delete [] array;
|
||||
|
||||
m_pos += n;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
bool write_strings(size_t a_number,void* a_array) {
|
||||
size_t sz = m_size*a_number;
|
||||
char* buffer = new char[sz];
|
||||
{char* pos = buffer;
|
||||
for(size_t index=0;index<sz;index++,pos++) *pos = ' ';}
|
||||
|
||||
{char** strings = (char**)a_array;
|
||||
char* pos = buffer;
|
||||
size_t ls;
|
||||
for(size_t index=0;index<a_number;index++) {
|
||||
char* ss = strings[index];
|
||||
ls = ::strlen(ss);
|
||||
::memcpy(pos,ss,ls); //do not copy the ending 0.
|
||||
*(pos+m_size-1) = 0;
|
||||
pos += m_size;
|
||||
}}
|
||||
|
||||
if(!m_pos) {
|
||||
unsigned int chunked = 32*m_size; //<size>A strings.
|
||||
if(!write_array<char>(m_group,s_pages(),sz,buffer,chunked,m_compress)) {
|
||||
m_out << "pages::write_strings : write_strings() failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
m_dataset = tools_H5Dopen(m_group,s_pages().c_str());
|
||||
if(m_dataset<0) {
|
||||
m_out << "pages::write_strings : H5Dopen failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(!write_append_array_dataset<char>(m_dataset,sz,buffer)) {
|
||||
m_out << "pages::write_strings : write_append_strings() failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_pos += a_number;
|
||||
m_entries = m_pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read_strings(size_t a_size,void* a_array) {
|
||||
unsigned int _size = a_size*m_size;
|
||||
unsigned int n = 0;
|
||||
char* array = 0;
|
||||
if(!read_sub_array<char>(m_group,s_pages(),m_pos,_size,n,array)) {
|
||||
m_out << "pages::read_strings : read_sub_array<char>() failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(n!=_size) {
|
||||
m_out << "pages::read_strings : size mismatch. Requested " << _size << ", got "<< n << "." << std::endl;
|
||||
delete [] array;
|
||||
return false;
|
||||
}
|
||||
char* pos = array;
|
||||
{char** strings = (char**)a_array;
|
||||
for(size_t index=0;index<a_size;index++) {
|
||||
::memcpy(strings[index],pos,m_size*sizeof(char));
|
||||
pos += m_size;
|
||||
}}
|
||||
delete [] array;
|
||||
m_pos += n;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
protected:
|
||||
std::ostream& m_out;
|
||||
std::string m_name;
|
||||
std::string m_form;
|
||||
//int m_type;
|
||||
//unsigned int m_size;
|
||||
hid_t m_group;
|
||||
hid_t m_dataset;
|
||||
bool m_write;
|
||||
unsigned int m_compress; //if write.
|
||||
tools::uint64 m_entries;
|
||||
tools::uint64 m_pos;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,193 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_store
|
||||
#define tools_hdf5_store
|
||||
|
||||
#include "pages"
|
||||
|
||||
#include <tools/vmanip>
|
||||
#include <tools/sout>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
class store {
|
||||
public:
|
||||
TOOLS_SCLASS(tools::hdf5::store)
|
||||
public:
|
||||
store(std::ostream& a_out,hid_t a_group,const std::string& a_name,bool a_write,unsigned int a_compress)
|
||||
:m_out(a_out)
|
||||
,m_write(a_write)
|
||||
,m_compress(a_compress) //used at write.
|
||||
,m_group(-1)
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
if(m_write) {
|
||||
if(a_name.empty()) {
|
||||
a_out << "tools::hdf5::store::store : string a_name is empty." << std::endl;
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
m_group = tools_H5Gcreate(a_group,a_name.c_str(),0);
|
||||
if(m_group<0) {
|
||||
a_out << "tools::hdf5::store::store : can't create " << a_name << " group." << std::endl;
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
if(!write_atb(m_group,"class",s_class())) {
|
||||
m_out << "tools::hdf5::store::store : write_atb(class) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
int v = 1;
|
||||
if(!write_scalar_atb<int>(m_group,"version",v)) {
|
||||
m_out << "tools::hdf5::store::store : write_scalar_atb(version) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
} else { // to read.
|
||||
m_group = tools_H5Gopen(a_group,a_name.c_str());
|
||||
if(m_group<0) {
|
||||
a_out << "tools::hdf5::store::store : can't open " << a_name << " group." << std::endl;
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> names;
|
||||
if(!read_array_string(m_group,s_names(),names)) {
|
||||
m_out << "tools::hdf5::store::store : read_array_string(names) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> TFORMs;
|
||||
if(!read_array_string(m_group,s_forms(),TFORMs)) {
|
||||
m_out << "tools::hdf5::store::store : read_array_string(tforms) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
if(names.size()!=TFORMs.size()) {
|
||||
m_out << "tools::hdf5::store::store : names/TFORMs size mismatch." << std::endl;
|
||||
m_out << "names :" << std::endl;
|
||||
{tools_vforcit(std::string,names,it) m_out << *it << std::endl;}
|
||||
m_out << "TFORMs :" << std::endl;
|
||||
{tools_vforcit(std::string,TFORMs,it) m_out << *it << std::endl;}
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
for(size_t index=0;index<names.size();index++) {
|
||||
if(!create_pages(names[index],TFORMs[index])) {
|
||||
m_out << "tools::hdf5::store::store : can't create hdf5_column "
|
||||
<< tools::sout(names[index]) << "." << std::endl;
|
||||
tools::safe_clear(m_pagess);
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual ~store(){
|
||||
if(m_write) {
|
||||
tools::uint64 _entries;
|
||||
if(!entries(_entries)) {
|
||||
m_out << "tools::hdf5::store::~store : not same entries on all columns. Write 0." << std::endl;
|
||||
}
|
||||
if(!write_scalar<tools::uint64>(m_group,s_entries(),_entries)) {
|
||||
m_out << "tools::hdf5::store::~store : write_scalar(entries) failed." << std::endl;
|
||||
}
|
||||
if(!write_scalar<unsigned int>(m_group,s_columns(),m_pagess.size())) {
|
||||
m_out << "tools::hdf5::store::~store : write_scalar(columns) failed." << std::endl;
|
||||
}
|
||||
{std::vector<std::string> names;
|
||||
tools_vforcit(pages*,m_pagess,it) names.push_back((*it)->name());
|
||||
//{m_out << "debug : write : names :" << std::endl;
|
||||
// tools_vforcit(std::string,names,it) m_out << *it << std::endl;}
|
||||
if(!write_array_string(m_group,s_names(),names)) {
|
||||
m_out << "tools::hdf5::store::~store : write_array_string(names) failed." << std::endl;
|
||||
}}
|
||||
{std::vector<std::string> TFORMs;
|
||||
tools_vforcit(pages*,m_pagess,it) TFORMs.push_back((*it)->form());
|
||||
//{m_out << "debug : write : TFORMs :" << std::endl;
|
||||
// tools_vforcit(std::string,TFORMs,it) m_out << *it << std::endl;}
|
||||
if(!write_array_string(m_group,s_forms(),TFORMs)) {
|
||||
m_out << "tools::hdf5::store::~store : write_array_string(tforms) failed." << std::endl;
|
||||
}}
|
||||
}
|
||||
tools::safe_clear(m_pagess);
|
||||
::H5Gclose(m_group);
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected:
|
||||
store(const store& a_from)
|
||||
:m_out(a_from.m_out)
|
||||
,m_name(a_from.m_name)
|
||||
,m_compress(a_from.m_compress)
|
||||
,m_group(-1)
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
store& operator=(const store&){return *this;}
|
||||
public:
|
||||
std::ostream& out() const {return m_out;}
|
||||
//bool fill(tools::uint32 &a_n){a_n = 0;return true;}
|
||||
|
||||
bool entries(tools::uint64& a_entries) const {
|
||||
if(m_pagess.empty()) {a_entries = 0;return true;}
|
||||
a_entries = m_pagess.front()->entries();
|
||||
tools_vforcit(pages*,m_pagess,it) {
|
||||
if((*it)->entries()!=a_entries) {
|
||||
m_out << "tools::hdf5::store::entries : not same entries on all columns."
|
||||
<< " Front " << a_entries << ", it " << (*it)->entries() << "." << std::endl;
|
||||
a_entries = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pages* create_pages(const std::string& a_name,const std::string& a_form) {
|
||||
//::printf("debug : create_pages %s %s\n",a_name.c_str(),a_form.c_str());
|
||||
pages* _pages = new pages(m_out,m_group,a_name,a_form,m_write,m_compress);
|
||||
if(!_pages->is_valid()) {
|
||||
m_out << "tools::hdf5::store::create_column : can't create pages." << std::endl;
|
||||
delete _pages;
|
||||
return 0;
|
||||
}
|
||||
m_pagess.push_back(_pages);
|
||||
return _pages;
|
||||
}
|
||||
/*
|
||||
pages* find_column(unsigned int a_index) {
|
||||
if(a_index>=m_pagess.size()) {
|
||||
m_out << "tools::hdf5::store::find_column : out of range index." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
return m_pagess[a_index];
|
||||
}
|
||||
const std::vector<pages*>& columns() const {return m_pagess;}*/
|
||||
|
||||
hid_t group() const {return m_group;}
|
||||
unsigned int compress_level() const {return m_compress;}
|
||||
protected:
|
||||
std::ostream& m_out;
|
||||
std::string m_name;
|
||||
bool m_write;
|
||||
unsigned int m_compress;
|
||||
hid_t m_group;
|
||||
std::vector<pages*> m_pagess;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,749 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_tools
|
||||
#define tools_hdf5_tools
|
||||
|
||||
#include "hdf5_h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool check_sizes(){
|
||||
if(sizeof(bool)!=1) return false;
|
||||
if(sizeof(char)!=1) return false;
|
||||
if(sizeof(short)!=2) return false;
|
||||
if(sizeof(int)!=4) return false;
|
||||
if(sizeof(float)!=4) return false;
|
||||
if(sizeof(double)!=8) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline int failure() {return -1;}
|
||||
|
||||
inline hid_t string_datatype(size_t aSize){
|
||||
// aSize should include the trailing null char.
|
||||
hid_t datatype = ::H5Tcopy(H5T_C_S1);
|
||||
if(datatype<0) return failure();
|
||||
|
||||
if(::H5Tset_size(datatype,aSize)<0) {
|
||||
::H5Tclose(datatype);
|
||||
return failure();
|
||||
}
|
||||
|
||||
if(::H5Tset_strpad(datatype,H5T_STR_NULLTERM)<0) {
|
||||
::H5Tclose(datatype);
|
||||
return failure();
|
||||
}
|
||||
|
||||
return datatype;
|
||||
}
|
||||
|
||||
inline hid_t basic_mem_type(hid_t a_file_type){
|
||||
H5T_class_t mclass = H5Tget_class(a_file_type);
|
||||
size_t msize = H5Tget_size(a_file_type);
|
||||
if(mclass==H5T_INTEGER) {
|
||||
H5T_sign_t msign = H5Tget_sign(a_file_type);
|
||||
if(msize==1) {
|
||||
if(msign==H5T_SGN_NONE) {
|
||||
return H5Tcopy(H5T_NATIVE_UCHAR);
|
||||
} else {
|
||||
return H5Tcopy(H5T_NATIVE_CHAR);
|
||||
}
|
||||
} else if(msize==4) {
|
||||
if(msign==H5T_SGN_NONE) {
|
||||
return H5Tcopy(H5T_NATIVE_UINT);
|
||||
} else {
|
||||
return H5Tcopy(H5T_NATIVE_INT);
|
||||
}
|
||||
} else if(msize==8) { //for osc_file::header::fDate.
|
||||
if(msign==H5T_SGN_NONE) {
|
||||
return H5Tcopy(H5T_NATIVE_UINT64);
|
||||
} else {
|
||||
return H5Tcopy(H5T_NATIVE_INT64);
|
||||
}
|
||||
} else {
|
||||
return failure();
|
||||
}
|
||||
} else if(mclass==H5T_FLOAT) {
|
||||
if(msize==4) {
|
||||
return H5Tcopy(H5T_NATIVE_FLOAT);
|
||||
} else if(msize==8) {
|
||||
return H5Tcopy(H5T_NATIVE_DOUBLE);
|
||||
} else {
|
||||
return failure();
|
||||
}
|
||||
} else if(mclass==H5T_STRING) {
|
||||
return H5Tcopy(a_file_type);
|
||||
}
|
||||
|
||||
return failure();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline hid_t compound_mem_type(hid_t a_file_type){
|
||||
// FIXME : In principle H5T_get_native_type should do the job but it crashes.
|
||||
|
||||
H5T_class_t t_class = H5Tget_class(a_file_type);
|
||||
if(t_class!=H5T_COMPOUND) return failure();
|
||||
|
||||
size_t sz = H5Tget_size(a_file_type);
|
||||
//printf("debug : compound_mem_type : sz %lu\n",sz);
|
||||
|
||||
hid_t memtype = ::H5Tcreate(H5T_COMPOUND,sz);
|
||||
if(memtype<0) return failure();
|
||||
|
||||
//FIXME : WARNING : is order the booked order ?
|
||||
|
||||
int mn = H5Tget_nmembers(a_file_type);
|
||||
std::vector<unsigned int> szs(mn);
|
||||
//printf("debug : members : %d\n",mn);
|
||||
for(int index=0;index<mn;index++) {
|
||||
char* mname = H5Tget_member_name(a_file_type,index);
|
||||
size_t moffset = H5Tget_member_offset(a_file_type,index);
|
||||
hid_t mtype = H5Tget_member_type(a_file_type,index);
|
||||
//printf("debug : members : %d (%d) : %s : begin\n",index,mn,mname);
|
||||
|
||||
{H5T_class_t mclass = H5Tget_class(mtype);
|
||||
if( (mclass==H5T_INTEGER) ||
|
||||
(mclass==H5T_STRING) ||
|
||||
(mclass==H5T_FLOAT) ) {
|
||||
hid_t mmemtype = basic_mem_type(mtype);
|
||||
if(mmemtype<0) {
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
if(H5Tinsert(memtype,mname,moffset,mmemtype)<0) {
|
||||
::H5Tclose(mmemtype);
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
::H5Tclose(mmemtype);
|
||||
|
||||
} else if(mclass==H5T_ARRAY) {
|
||||
int dimn = ::H5Tget_array_ndims(mtype); //Should be 1;
|
||||
hsize_t* dims = new hsize_t[dimn];
|
||||
int* perms = new int[dimn];
|
||||
if(tools_H5Tget_array_dims(mtype,dims,perms)<0) {
|
||||
delete [] dims;
|
||||
delete [] perms;
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
hid_t base_type = H5Tget_super(mtype);
|
||||
if(base_type<0) {
|
||||
delete [] dims;
|
||||
delete [] perms;
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
hid_t mmemtype = basic_mem_type(base_type);
|
||||
if(mmemtype<0) {
|
||||
delete [] dims;
|
||||
delete [] perms;
|
||||
::H5Tclose(base_type);
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
::H5Tclose(base_type);
|
||||
hid_t array_type = tools_H5Tarray_create(mmemtype,dimn,dims,perms);
|
||||
delete [] dims;
|
||||
delete [] perms;
|
||||
if(array_type<0) {
|
||||
::H5Tclose(mmemtype);
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
::H5Tclose(mmemtype);
|
||||
|
||||
if(H5Tinsert(memtype,mname,moffset,array_type)<0) {
|
||||
::H5Tclose(array_type);
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
::H5Tclose(array_type);
|
||||
|
||||
} else if(mclass==H5T_COMPOUND) {
|
||||
hid_t mmemtype = compound_mem_type(mtype);
|
||||
if(memtype<0) {
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
if(H5Tinsert(memtype,mname,moffset,mmemtype)<0) {
|
||||
::H5Tclose(mmemtype);
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
::H5Tclose(mmemtype);
|
||||
} else {
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}}
|
||||
::H5Tclose(mtype);
|
||||
//printf("debug : compound_mem_type : %d (%d) : %s : end\n",index,mn,mname);
|
||||
if(mname) ::free(mname);
|
||||
}
|
||||
|
||||
return memtype;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#include "atb"
|
||||
#include <string>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool read_atb(hid_t aID,const std::string& a_name,std::string& aData,unsigned int aSize = 100){
|
||||
// From H5LT.c/H5LTget_attribute_string.
|
||||
if(!H5LT_find_attribute(aID,a_name.c_str())) {aData.clear();return false;}
|
||||
char* b = new char[aSize];
|
||||
if(H5LT_get_attribute_disk(aID,a_name.c_str(),b)<0) {
|
||||
delete [] b;
|
||||
return false;
|
||||
}
|
||||
aData = std::string(b);
|
||||
delete [] b;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_atb(hid_t aID,const std::string& a_name,unsigned int& aData){
|
||||
if(!H5LT_find_attribute(aID,a_name.c_str())) {aData=0;return false;}
|
||||
if(H5LT_get_attribute_mem(aID,a_name.c_str(),H5T_NATIVE_UINT,&aData)<0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_atb(hid_t aID,const std::string& a_name,int& aData){
|
||||
if(!H5LT_find_attribute(aID,a_name.c_str())) {aData=0;return false;}
|
||||
if(H5LT_get_attribute_mem(aID,a_name.c_str(),H5T_NATIVE_INT,&aData)<0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline hid_t H5T_STD_U8XX() {return H5T_STD_U8LE;}
|
||||
inline hid_t H5T_STD_U32XX() {return H5T_STD_U32LE;}
|
||||
inline hid_t H5T_STD_U64XX() {return H5T_STD_U64LE;}
|
||||
inline hid_t H5T_STD_I8XX() {return H5T_STD_I8LE;}
|
||||
inline hid_t H5T_STD_I16XX() {return H5T_STD_I16LE;}
|
||||
inline hid_t H5T_STD_I32XX() {return H5T_STD_I32LE;}
|
||||
inline hid_t H5T_STD_I64XX() {return H5T_STD_I64LE;}
|
||||
inline hid_t H5T_IEEE_F32XX() {return H5T_IEEE_F32LE;}
|
||||
inline hid_t H5T_IEEE_F64XX() {return H5T_IEEE_F64LE;}
|
||||
|
||||
inline bool dataset_vec_size(hid_t a_loc,const std::string& a_name,hsize_t& a_size) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
a_size = 0;
|
||||
return false; // data set not found.
|
||||
}
|
||||
|
||||
hid_t file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int dimn = H5Sget_simple_extent_ndims(file_space);
|
||||
if(dimn<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
return false;
|
||||
}
|
||||
if(dimn!=1) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
return false;
|
||||
}
|
||||
//printf("debug : read dimn %d\n",dimn);
|
||||
|
||||
hsize_t dims[1];
|
||||
{if(H5Sget_simple_extent_dims(file_space,dims,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
a_size = dims[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool write_atb(hid_t aDS,const std::string& a_name,const std::string& aData){
|
||||
// From H5LT.c/H5LTset_attribute_string.
|
||||
int has_attr = H5LT_find_attribute(aDS,a_name.c_str());
|
||||
if(has_attr==1) {
|
||||
if(H5Adelete(aDS,a_name.c_str())<0) return false;
|
||||
}
|
||||
|
||||
hid_t datatype = string_datatype(aData.size()+1);
|
||||
if(datatype<0) return false;
|
||||
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) {
|
||||
::H5Tclose(datatype);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t aid = tools_H5Acreate(aDS,a_name.c_str(),datatype,scalar,H5P_DEFAULT);
|
||||
if(aid<0) {
|
||||
::H5Sclose(scalar);
|
||||
::H5Tclose(datatype);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Awrite(aid,datatype,aData.c_str())<0) {
|
||||
::H5Aclose(aid);
|
||||
::H5Sclose(scalar);
|
||||
::H5Tclose(datatype);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Aclose(aid);
|
||||
::H5Sclose(scalar);
|
||||
::H5Tclose(datatype);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool write_bool(hid_t a_loc,const std::string& a_name,bool aData) {
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(compact<0) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
if(H5Pset_layout(compact,H5D_COMPACT)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),H5T_STD_U8XX(),scalar,compact);
|
||||
if(dataset<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char data = aData?1:0;
|
||||
if(::H5Dwrite(dataset,H5T_NATIVE_UCHAR,H5S_ALL,H5S_ALL,H5P_DEFAULT,&data)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool write_string(hid_t a_loc,const std::string& a_name,const std::string& aString) {
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(compact<0) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Pset_layout(compact,H5D_COMPACT)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
// From H5LTmakge_dataset_string.
|
||||
hid_t filetype = string_datatype(aString.size()+1);
|
||||
if(filetype<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),filetype,scalar,compact);
|
||||
if(dataset<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Tclose(filetype);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t memtype = filetype;
|
||||
if(H5Dwrite(dataset,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,aString.c_str())<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(filetype);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(filetype);
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#include <tools/buf2lines>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool write_array_string(hid_t a_loc,const std::string& a_name,const std::vector<std::string>& a_array) {
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
// From H5LTmake_dataset_string.
|
||||
size_t sz;
|
||||
char* buffer;
|
||||
if(!tools::strings2buf(a_array,sz,buffer)) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t filetype = string_datatype(sz);
|
||||
if(filetype<0) {
|
||||
delete [] buffer;
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),filetype,scalar,H5P_DEFAULT);
|
||||
if(dataset<0) {
|
||||
delete [] buffer;
|
||||
::H5Tclose(filetype);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t memtype = filetype;
|
||||
if(H5Dwrite(dataset,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,buffer)<0) {
|
||||
delete [] buffer;
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(filetype);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
delete [] buffer;
|
||||
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(filetype);
|
||||
::H5Sclose(scalar);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool write_object(hid_t a_loc,const std::string& a_name,hid_t a_file_type,char* aData) {
|
||||
unsigned int chunked = 0;
|
||||
unsigned int compress = 0;
|
||||
|
||||
hid_t cpt = -1;
|
||||
if(compress || chunked) {
|
||||
cpt = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(cpt<0) return false;
|
||||
if(chunked) {
|
||||
if(H5Pset_layout(cpt,H5D_CHUNKED)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
hsize_t cdims[1];
|
||||
cdims[0] = chunked;
|
||||
if(H5Pset_chunk(cpt,1,cdims)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(H5Pset_layout(cpt,H5D_COMPACT)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(compress) {
|
||||
if(H5Pset_deflate(cpt,compress>9?9:compress)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpt = H5P_DEFAULT;
|
||||
}
|
||||
|
||||
hsize_t dims[1];
|
||||
dims[0] = 1;
|
||||
hid_t simple = ::H5Screate_simple(1,dims,NULL);
|
||||
if(simple<0) {
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t mem_type = compound_mem_type(a_file_type);
|
||||
if(mem_type<0) {
|
||||
::H5Sclose(simple);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),a_file_type,simple,cpt);
|
||||
if(dataset<0) {
|
||||
::H5Tclose(mem_type);
|
||||
::H5Sclose(simple);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dwrite(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,aData)<0) {
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(mem_type);
|
||||
::H5Sclose(simple);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(mem_type);
|
||||
::H5Sclose(simple);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_string(hid_t a_loc,const std::string& a_name,std::string& aString) {
|
||||
// From H5LTread_dataset_string.
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
aString.clear();
|
||||
return false; // data set not found.
|
||||
}
|
||||
|
||||
hid_t filetype = H5Dget_type(dataset);
|
||||
if(filetype<0) {
|
||||
::H5Dclose(dataset);
|
||||
aString.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
H5T_class_t t_class = H5Tget_class(filetype);
|
||||
if(t_class!=H5T_STRING) {
|
||||
::H5Tclose(filetype);
|
||||
::H5Dclose(dataset);
|
||||
aString.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t sz = H5Tget_size(filetype);
|
||||
::H5Tclose(filetype);
|
||||
if(!sz) {
|
||||
::H5Dclose(dataset);
|
||||
aString.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// We could have use filetype since, for string,
|
||||
// file type is the same than memory type.
|
||||
hid_t memtype = string_datatype(sz);
|
||||
if(memtype<0) {
|
||||
::H5Dclose(dataset);
|
||||
aString.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
char* buff = new char[sz];
|
||||
herr_t stat = H5Dread(dataset,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,buff);
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
if(stat<0) {
|
||||
delete [] buff;
|
||||
aString.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = sz-1;
|
||||
aString.resize(len,0);
|
||||
for(size_t index=0;index<len;index++) aString[index] = buff[index];
|
||||
|
||||
delete [] buff;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_object(hid_t a_loc,const std::string& a_name,size_t& a_size,char*& aData) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t filetype = H5Dget_type(dataset);
|
||||
if(filetype<0) {
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
H5T_class_t t_class = H5Tget_class(filetype);
|
||||
if(t_class!=H5T_COMPOUND) {
|
||||
::H5Tclose(filetype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t sz = H5Tget_size(filetype);
|
||||
if(!sz) {
|
||||
::H5Tclose(filetype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t memtype = compound_mem_type(filetype);
|
||||
if(memtype<0) {
|
||||
::H5Tclose(filetype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Tclose(filetype);
|
||||
|
||||
hid_t dataspace = H5Dget_space(dataset);
|
||||
if(dataspace<0) {
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) {
|
||||
::H5Sclose(dataspace);
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
char* buffer = new char[sz];
|
||||
if(H5Dread(dataset,memtype,scalar,dataspace,H5P_DEFAULT,buffer)<0) {
|
||||
delete [] buffer;
|
||||
::H5Sclose(scalar);
|
||||
::H5Sclose(dataspace);
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(scalar);
|
||||
::H5Sclose(dataspace);
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
a_size = sz;
|
||||
aData = buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_array_string(hid_t a_loc,const std::string& a_name,std::vector<std::string>& a_array) {
|
||||
a_array.clear();
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) return false;
|
||||
|
||||
hid_t filetype = H5Dget_type(dataset);
|
||||
if(filetype<0) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
H5T_class_t t_class = H5Tget_class(filetype);
|
||||
if(t_class!=H5T_STRING) {
|
||||
::H5Tclose(filetype);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t sz = H5Tget_size(filetype);
|
||||
::H5Tclose(filetype);
|
||||
if(!sz) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
// We could have use filetype since, for string,
|
||||
// file type is the same than memory type.
|
||||
hid_t memtype = string_datatype(sz);
|
||||
if(memtype<0) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
char* buffer = new char[sz];
|
||||
herr_t stat = H5Dread(dataset,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,buffer);
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
if(stat<0) {
|
||||
delete [] buffer;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!tools::buf2strings(sz,buffer,a_array)) {
|
||||
delete [] buffer;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete [] buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -244,6 +244,21 @@ public:
|
||||
m_edges = a_from.m_edges;
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
bool equals(const axis& a_from) const {
|
||||
if(&a_from==this) return true;
|
||||
if(m_offset!=a_from.m_offset) return false;
|
||||
if(m_number_of_bins!=a_from.m_number_of_bins) return false;
|
||||
if(m_minimum_value!=a_from.m_minimum_value) return false;
|
||||
if(m_maximum_value!=a_from.m_maximum_value) return false;
|
||||
if(m_fixed!=a_from.m_fixed) return false;
|
||||
if(m_bin_width!=a_from.m_bin_width) return false;
|
||||
if(m_edges!=a_from.m_edges) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==(const axis& a_from) const {return equals(a_from);}
|
||||
bool operator!=(const axis& a_from) const {return !equals(a_from);}
|
||||
|
||||
public:
|
||||
TO m_offset;
|
||||
|
||||
@@ -17,7 +17,8 @@ class b1 : public base_histo<TC,TO,TN,TW,TH> {
|
||||
protected:
|
||||
enum {AxisX=0};
|
||||
public:
|
||||
typedef histo::axis<TC,TO> axis_t;
|
||||
typedef base_histo<TC,TO,TN,TW,TH> base_histo_t;
|
||||
typedef typename parent::axis_t axis_t;
|
||||
typedef typename parent::bn_t bn_t;
|
||||
public:
|
||||
virtual TH bin_error(int) const = 0; //for print
|
||||
@@ -166,7 +167,11 @@ protected:
|
||||
virtual ~b1(){}
|
||||
protected:
|
||||
b1(const b1& a_from):parent(a_from){}
|
||||
b1& operator=(const b1& a_from) {parent::operator=(a_from);return *this;}
|
||||
b1& operator=(const b1& a_from) {
|
||||
if(&a_from==this) return *this;
|
||||
parent::operator=(a_from);
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
bool configure(bn_t aXnumber,TC aXmin,TC aXmax){
|
||||
std::vector<bn_t> nbins;
|
||||
|
||||
@@ -17,7 +17,8 @@ class b2 : public base_histo<TC,TO,TN,TW,TH> {
|
||||
protected:
|
||||
enum {AxisX=0,AxisY=1};
|
||||
public:
|
||||
typedef axis<TC,TO> axis_t;
|
||||
typedef base_histo<TC,TO,TN,TW,TH> base_histo_t;
|
||||
typedef typename parent::axis_t axis_t;
|
||||
typedef typename parent::bn_t bn_t;
|
||||
public:
|
||||
virtual TH bin_error(int,int) const = 0; //for print
|
||||
|
||||
@@ -15,7 +15,8 @@ template <class TC,class TO,class TN,class TW,class TH>
|
||||
class b3 : public base_histo<TC,TO,TN,TW,TH> {
|
||||
typedef base_histo<TC,TO,TN,TW,TH> parent;
|
||||
public:
|
||||
typedef axis<TC,TO> axis_t;
|
||||
typedef base_histo<TC,TO,TN,TW,TH> base_histo_t;
|
||||
typedef typename parent::axis_t axis_t;
|
||||
typedef typename parent::bn_t bn_t;
|
||||
protected:
|
||||
enum {AxisX=0,AxisY=1,AxisZ=2};
|
||||
|
||||
@@ -74,11 +74,16 @@ protected:
|
||||
}
|
||||
|
||||
base_histo& operator=(const base_histo& a_from) {
|
||||
if(&a_from==this) return *this;
|
||||
parent::operator=(a_from);
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
bool equals(const base_histo& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
|
||||
return parent::equals(a_from,a_prec,a_fabs);
|
||||
}
|
||||
|
||||
const std::string& title() const {return parent::m_title;}
|
||||
bool set_title(const std::string& a_title){parent::m_title = a_title;return true;}
|
||||
dim_t dimension() const {return parent::m_dimension;}
|
||||
|
||||
@@ -145,7 +145,8 @@ public:
|
||||
if(!m_histo) const_cast<c1d&>(*this).convert_to_histogram();
|
||||
return *m_histo;
|
||||
}
|
||||
bool fill_histogram(histo::h1d& a_histo) const {
|
||||
template <class HISTO>
|
||||
bool fill_histogram(HISTO& a_histo) const {
|
||||
size_t number = m_xs.size();
|
||||
for(size_t index=0;index<number;index++) {
|
||||
if(!a_histo.fill(m_xs[index],m_ws[index])) return false;
|
||||
@@ -168,7 +169,7 @@ public:
|
||||
,m_cnv_x_num(0),m_cnv_x_min(0),m_cnv_x_max(0),m_histo(0)
|
||||
{}
|
||||
|
||||
c1d(const std::string& a_title,int aLimit = -1)
|
||||
c1d(const std::string& a_title,int aLimit = base_cloud::UNLIMITED())
|
||||
:base_cloud(aLimit)
|
||||
,m_lower_x(0),m_upper_x(0)
|
||||
,m_Sxw(0),m_Sx2w(0)
|
||||
@@ -215,6 +216,11 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
public: //AIDA API
|
||||
double lowerEdge() const {return lower_edge();}
|
||||
double upperEdge() const {return upper_edge();}
|
||||
template <class HISTO>
|
||||
bool fillHistogram(HISTO& a_histo) const {return fill_histogram<HISTO>(a_histo);}
|
||||
protected:
|
||||
void clear(){
|
||||
m_lower_x = 0;
|
||||
|
||||
@@ -23,38 +23,37 @@ public:
|
||||
bool set_title(const std::string&);
|
||||
unsigned int dimension() const {return 2;}
|
||||
bool reset();
|
||||
unsigned int entries() const;
|
||||
unsigned int entries() const { return m_histo ? m_histo->all_entries() : (unsigned int)m_ws.size();}
|
||||
public:
|
||||
double sum_of_weights() const;
|
||||
double sum_of_weights() const { return (m_histo ? m_histo->sum_bin_heights() : m_Sw);}
|
||||
bool convert_to_histogram();
|
||||
bool is_converted() const;
|
||||
bool is_converted() const {return m_histo ? true : false;}
|
||||
bool scale(double);
|
||||
public:
|
||||
bool fill(double,double,double = 1);
|
||||
double lower_edge_x() const;
|
||||
double upper_edge_x() const;
|
||||
double lower_edge_y() const;
|
||||
double upper_edge_y() const;
|
||||
double value_x(unsigned int) const;
|
||||
double value_y(unsigned int) const;
|
||||
double weight(unsigned int) const;
|
||||
double mean_x() const;
|
||||
double mean_y() const;
|
||||
double lower_edge_x() const {return m_histo ? m_histo->axis_x().lower_edge() : m_lower_x;}
|
||||
double lower_edge_y() const { return m_histo ? m_histo->axis_y().lower_edge() : m_lower_y;}
|
||||
double upper_edge_x() const { return m_histo ? m_histo->axis_x().upper_edge() : m_upper_x;}
|
||||
double upper_edge_y() const { return m_histo ? m_histo->axis_y().upper_edge() : m_upper_y;}
|
||||
double value_x(unsigned int aIndex) const { return m_histo ? 0 : m_xs[aIndex];}
|
||||
double value_y(unsigned int aIndex) const { return m_histo ? 0 : m_ys[aIndex];}
|
||||
double weight(unsigned int aIndex) const { return m_histo ? 0 : m_ws[aIndex];}
|
||||
double mean_x() const {return m_histo ? m_histo->mean_x() : (m_Sw?m_Sxw/m_Sw:0);}
|
||||
double mean_y() const {return m_histo ? m_histo->mean_y() : (m_Sw?m_Syw/m_Sw:0);}
|
||||
double rms_x() const;
|
||||
double rms_y() const;
|
||||
bool convert(unsigned int,double,double,
|
||||
unsigned int,double,double);
|
||||
bool convert(unsigned int,double,double,unsigned int,double,double);
|
||||
bool convert(const std::vector<double>&,const std::vector<double>&);
|
||||
const histo::h2d& histogram() const;
|
||||
bool fill_histogram(histo::h2d& a_histo) const {
|
||||
template <class HISTO>
|
||||
bool fill_histogram(HISTO& a_histo) const {
|
||||
size_t number = m_xs.size();
|
||||
for(size_t index=0;index<number;index++) {
|
||||
if(!a_histo.fill(m_xs[index],m_ys[index],m_ws[index])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool set_conversion_parameters(unsigned int,double,double,
|
||||
unsigned int,double,double);
|
||||
bool set_conversion_parameters(unsigned int,double,double,unsigned int,double,double);
|
||||
|
||||
bool set_histogram(h2d* a_histo){ //we take ownership of a_histo.
|
||||
reset();
|
||||
@@ -63,7 +62,7 @@ public:
|
||||
}
|
||||
public:
|
||||
c2d();
|
||||
c2d(const std::string&,int=-1);
|
||||
c2d(const std::string&,int=base_cloud::UNLIMITED());
|
||||
virtual ~c2d(){delete m_histo;}
|
||||
public:
|
||||
c2d(const c2d& a_from)
|
||||
@@ -117,6 +116,13 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
public: //AIDA API
|
||||
double lowerEdgeX() const {return lower_edge_x();}
|
||||
double lowerEdgeY() const {return lower_edge_y();}
|
||||
double upperEdgeX() const {return upper_edge_x();}
|
||||
double upperEdgeY() const {return upper_edge_y();}
|
||||
template <class HISTO>
|
||||
bool fillHistogram(HISTO& a_histo) const {return fill_histogram<HISTO>(a_histo);}
|
||||
protected:
|
||||
void clear();
|
||||
protected:
|
||||
@@ -187,9 +193,6 @@ c2d::c2d(const std::string& a_title,int aLimit)
|
||||
set_title(a_title);
|
||||
}
|
||||
|
||||
inline
|
||||
bool c2d::is_converted() const {return m_histo ? true : false;}
|
||||
|
||||
inline
|
||||
void c2d::clear(){
|
||||
m_lower_x = 0;
|
||||
@@ -335,53 +338,6 @@ const h2d& c2d::histogram() const {
|
||||
return *m_histo;
|
||||
}
|
||||
|
||||
inline
|
||||
unsigned int c2d::entries() const {
|
||||
return m_histo ? m_histo->all_entries() : (unsigned int)m_ws.size();
|
||||
}
|
||||
|
||||
inline
|
||||
double c2d::sum_of_weights() const {
|
||||
return (m_histo ? m_histo->sum_bin_heights() : m_Sw);
|
||||
}
|
||||
|
||||
inline
|
||||
double c2d::lower_edge_x() const {
|
||||
return m_histo ? m_histo->axis_x().lower_edge() : m_lower_x;
|
||||
}
|
||||
inline
|
||||
double c2d::lower_edge_y() const {
|
||||
return m_histo ? m_histo->axis_y().lower_edge() : m_lower_y;
|
||||
}
|
||||
inline
|
||||
double c2d::upper_edge_x() const {
|
||||
return m_histo ? m_histo->axis_x().upper_edge() : m_upper_x;
|
||||
}
|
||||
inline
|
||||
double c2d::upper_edge_y() const {
|
||||
return m_histo ? m_histo->axis_y().upper_edge() : m_upper_y;
|
||||
}
|
||||
inline
|
||||
double c2d::value_x(unsigned int aIndex) const {
|
||||
return m_histo ? 0 : m_xs[aIndex];
|
||||
}
|
||||
inline
|
||||
double c2d::value_y(unsigned int aIndex) const {
|
||||
return m_histo ? 0 : m_ys[aIndex];
|
||||
}
|
||||
inline
|
||||
double c2d::weight(unsigned int aIndex) const {
|
||||
return m_histo ? 0 : m_ws[aIndex];
|
||||
}
|
||||
|
||||
inline
|
||||
double c2d::mean_x() const {
|
||||
return m_histo ? m_histo->mean_x() : (m_Sw?m_Sxw/m_Sw:0);
|
||||
}
|
||||
inline
|
||||
double c2d::mean_y() const {
|
||||
return m_histo ? m_histo->mean_y() : (m_Sw?m_Syw/m_Sw:0);
|
||||
}
|
||||
inline
|
||||
double c2d::rms_x() const {
|
||||
double rms = 0; //FIXME nan.
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
}
|
||||
public:
|
||||
c3d();
|
||||
c3d(const std::string&,int=-1);
|
||||
c3d(const std::string&,int=base_cloud::UNLIMITED());
|
||||
virtual ~c3d(){delete m_histo;}
|
||||
public:
|
||||
c3d(const c3d& a_from)
|
||||
|
||||
@@ -152,11 +152,11 @@ public:
|
||||
void clear() {m_points.clear();}
|
||||
size_t size() const {return m_points.size();}
|
||||
|
||||
const data_point& point(unsigned int a_index) const {
|
||||
const data_point& point(size_t a_index) const {
|
||||
//WARNING : no check done on a_index.
|
||||
return m_points[a_index];
|
||||
}
|
||||
data_point& point(unsigned int a_index) {
|
||||
data_point& point(size_t a_index) {
|
||||
//WARNING : no check done on a_index.
|
||||
return m_points[a_index];
|
||||
}
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
return m_points.back();
|
||||
}
|
||||
|
||||
bool remove_point(unsigned int a_index) {
|
||||
bool remove_point(size_t a_index) {
|
||||
bool done = false;
|
||||
if(a_index<m_points.size()){
|
||||
std::vector<data_point>::iterator it = m_points.begin();
|
||||
|
||||
@@ -21,7 +21,7 @@ class h1 : public b1<TC,TO,TN,TW,TH> {
|
||||
public:
|
||||
typedef histo_data<TC,TO,TN,TW> hd_t;
|
||||
typedef typename parent::bn_t bn_t;
|
||||
typedef histo::axis<TC,TO> axis_t;
|
||||
typedef typename parent::axis_t axis_t;
|
||||
protected:
|
||||
virtual TH get_bin_height(TO a_offset) const { //TH should be the same as TW
|
||||
return parent::m_bin_Sw[a_offset];
|
||||
@@ -119,6 +119,28 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_bin_content(bn_t a_ibin,TN& a_entries,TW& a_Sw,TW& a_Sw2,TC& a_Sxw,TC& a_Sx2w) {
|
||||
if(parent::m_dimension!=1) {
|
||||
a_entries = 0;a_Sw = 0;a_Sw2 = 0;a_Sxw = 0;a_Sx2w = 0;
|
||||
return false;
|
||||
}
|
||||
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) {
|
||||
a_entries = 0;a_Sw = 0;a_Sw2 = 0;a_Sxw = 0;a_Sx2w = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
TO offset = a_ibin;
|
||||
|
||||
a_entries = parent::m_bin_entries[offset];
|
||||
a_Sw = parent::m_bin_Sw[offset];
|
||||
a_Sw2 = parent::m_bin_Sw2[offset];
|
||||
|
||||
a_Sxw = parent::m_bin_Sxw[offset][0];
|
||||
a_Sx2w = parent::m_bin_Sx2w[offset][0];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool add(const h1& a_histo){
|
||||
parent::base_add(a_histo);
|
||||
return true;
|
||||
@@ -198,6 +220,16 @@ public:
|
||||
*this = *new_h;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool equals_TH(const h1& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
|
||||
if(!parent::equals_TH(a_from,a_prec,a_fabs,true)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void not_a_profile() const {}
|
||||
|
||||
public: //CERN-ROOT API (for MEMPHYS sim).
|
||||
bool Fill(TC aX,TW aWeight = 1) {return fill(aX,aWeight);}
|
||||
|
||||
public:
|
||||
h1(const std::string& a_title,bn_t aXnumber,TC aXmin,TC aXmax)
|
||||
@@ -210,6 +242,7 @@ public:
|
||||
public:
|
||||
h1(const h1& a_from):parent(a_from){}
|
||||
h1& operator=(const h1& a_from){
|
||||
if(&a_from==this) return *this;
|
||||
parent::operator=(a_from);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ public:
|
||||
}
|
||||
const std::string& s_cls() const {return s_class();}
|
||||
public:
|
||||
h1d():parent("",10,0,1){} //for I/O when reading.
|
||||
|
||||
h1d(const std::string& a_title,unsigned int aXnumber,double aXmin,double aXmax)
|
||||
:parent(a_title,aXnumber,aXmin,aXmax){}
|
||||
|
||||
@@ -30,6 +32,7 @@ public:
|
||||
public:
|
||||
h1d(const h1d& a_from):parent(a_from){}
|
||||
h1d& operator=(const h1d& a_from){
|
||||
if(&a_from==this) return *this;
|
||||
parent::operator=(a_from);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -139,6 +139,42 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_bin_content(bn_t a_ibin,bn_t a_jbin,
|
||||
TN a_entries,TW a_Sw,TW a_Sw2,
|
||||
TC a_Sxw,TC a_Sx2w,TC a_Syw,TC a_Sy2w) {
|
||||
if(parent::m_dimension!=2) {
|
||||
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
|
||||
a_Sxw = 0;a_Sx2w = 0;
|
||||
a_Syw = 0;a_Sy2w = 0;
|
||||
return false;
|
||||
}
|
||||
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) {
|
||||
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
|
||||
a_Sxw = 0;a_Sx2w = 0;
|
||||
a_Syw = 0;a_Sy2w = 0;
|
||||
return false;
|
||||
}
|
||||
if(a_jbin>(parent::m_axes[1].m_number_of_bins+1)) {
|
||||
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
|
||||
a_Sxw = 0;a_Sx2w = 0;
|
||||
a_Syw = 0;a_Sy2w = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
TO offset = a_ibin + a_jbin * parent::m_axes[1].m_offset;
|
||||
|
||||
a_entries = parent::m_bin_entries[offset];
|
||||
a_Sw = parent::m_bin_Sw[offset];
|
||||
a_Sw2 = parent::m_bin_Sw2[offset];
|
||||
|
||||
a_Sxw = parent::m_bin_Sxw[offset][0];
|
||||
a_Sx2w = parent::m_bin_Sx2w[offset][0];
|
||||
a_Syw = parent::m_bin_Sxw[offset][1];
|
||||
a_Sy2w = parent::m_bin_Sx2w[offset][1];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool add(const h2& a_histo){
|
||||
parent::base_add(a_histo);
|
||||
return true;
|
||||
@@ -156,6 +192,16 @@ public:
|
||||
return parent::base_divide(a_histo);
|
||||
}
|
||||
|
||||
bool equals_TH(const h2& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
|
||||
if(!parent::equals_TH(a_from,a_prec,a_fabs,true)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void not_a_profile() const {}
|
||||
|
||||
public: //CERN-ROOT API
|
||||
bool Fill(TC aX,TC aY,TW aWeight = 1) {return fill(aX,aY,aWeight);}
|
||||
|
||||
public:
|
||||
h2(const std::string& a_title,bn_t aXnumber,TC aXmin,TC aXmax,bn_t aYnumber,TC aYmin,TC aYmax)
|
||||
:parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
|
||||
|
||||
@@ -18,6 +18,8 @@ public:
|
||||
}
|
||||
const std::string& s_cls() const {return s_class();}
|
||||
public:
|
||||
h2d():parent("",10,0,1,10,0,1){} //for I/O when reading.
|
||||
|
||||
h2d(const std::string& a_title,
|
||||
unsigned int aXnumber,double aXmin,double aXmax,
|
||||
unsigned int aYnumber,double aYmin,double aYmax)
|
||||
|
||||
@@ -21,6 +21,8 @@ public:
|
||||
}
|
||||
const std::string& s_cls() const {return s_class();}
|
||||
public:
|
||||
h2df():parent("",10,0,1,10,0,1){} //for I/O when reading.
|
||||
|
||||
h2df(const std::string& a_title,
|
||||
unsigned int aXnumber,float aXmin,float aXmax,
|
||||
unsigned int aYnumber,float aYmin,float aYmax)
|
||||
|
||||
@@ -162,6 +162,54 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_bin_content(bn_t a_ibin,bn_t a_jbin,bn_t a_kbin,
|
||||
TN a_entries,TW a_Sw,TW a_Sw2,
|
||||
TC a_Sxw,TC a_Sx2w,TC a_Syw,TC a_Sy2w,TC a_Szw,TC a_Sz2w) {
|
||||
if(parent::m_dimension!=3) {
|
||||
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
|
||||
a_Sxw = 0;a_Sx2w = 0;
|
||||
a_Syw = 0;a_Sy2w = 0;
|
||||
a_Szw = 0;a_Sz2w = 0;
|
||||
return false;
|
||||
}
|
||||
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) {
|
||||
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
|
||||
a_Sxw = 0;a_Sx2w = 0;
|
||||
a_Syw = 0;a_Sy2w = 0;
|
||||
a_Szw = 0;a_Sz2w = 0;
|
||||
return false;
|
||||
}
|
||||
if(a_jbin>(parent::m_axes[1].m_number_of_bins+1)) {
|
||||
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
|
||||
a_Sxw = 0;a_Sx2w = 0;
|
||||
a_Syw = 0;a_Sy2w = 0;
|
||||
a_Szw = 0;a_Sz2w = 0;
|
||||
return false;
|
||||
}
|
||||
if(a_kbin>(parent::m_axes[2].m_number_of_bins+1)) {
|
||||
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
|
||||
a_Sxw = 0;a_Sx2w = 0;
|
||||
a_Syw = 0;a_Sy2w = 0;
|
||||
a_Szw = 0;a_Sz2w = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
TO offset = a_ibin + a_jbin * parent::m_axes[1].m_offset + a_kbin * parent::m_axes[2].m_offset;
|
||||
|
||||
a_entries = parent::m_bin_entries[offset];
|
||||
a_Sw = parent::m_bin_Sw[offset];
|
||||
a_Sw2 = parent::m_bin_Sw2[offset];
|
||||
|
||||
a_Sxw = parent::m_bin_Sxw[offset][0];
|
||||
a_Sx2w = parent::m_bin_Sx2w[offset][0];
|
||||
a_Syw = parent::m_bin_Sxw[offset][1];
|
||||
a_Sy2w = parent::m_bin_Sx2w[offset][1];
|
||||
a_Szw = parent::m_bin_Sxw[offset][2];
|
||||
a_Sz2w = parent::m_bin_Sx2w[offset][2];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool add(const h3& a_histo){
|
||||
parent::base_add(a_histo);
|
||||
return true;
|
||||
@@ -179,6 +227,16 @@ public:
|
||||
return parent::base_divide(a_histo);
|
||||
}
|
||||
|
||||
bool equals_TH(const h3& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
|
||||
if(!parent::equals_TH(a_from,a_prec,a_fabs,true)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void not_a_profile() const {}
|
||||
|
||||
public: //CERN-ROOT API
|
||||
bool Fill(TC aX,TC aY,TC aZ,TW aWeight = 1) {return fill(aX,aY,aZ,aWeight);}
|
||||
|
||||
public:
|
||||
/*
|
||||
// Slices :
|
||||
|
||||
@@ -18,6 +18,8 @@ public:
|
||||
}
|
||||
const std::string& s_cls() const {return s_class();}
|
||||
public:
|
||||
h3d():parent("",10,0,1,10,0,1,10,0,1){} //for I/O when reading.
|
||||
|
||||
h3d(const std::string& a_title,
|
||||
unsigned int aXnumber,double aXmin,double aXmax,
|
||||
unsigned int aYnumber,double aYmin,double aYmax,
|
||||
|
||||
@@ -21,6 +21,8 @@ public:
|
||||
}
|
||||
const std::string& s_cls() const {return s_class();}
|
||||
public:
|
||||
h3df():parent("",10,0,1,10,0,1,10,0,1){} //for I/O when reading.
|
||||
|
||||
h3df(const std::string& a_title,
|
||||
unsigned int aXnumber,float aXmin,float aXmax,
|
||||
unsigned int aYnumber,float aYmin,float aYmax,
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <map> //for annotations
|
||||
|
||||
#include "axes"
|
||||
#include "../lina/eqT"
|
||||
//#include "../vmanip" //vequ
|
||||
|
||||
namespace tools {
|
||||
namespace histo {
|
||||
@@ -114,6 +116,56 @@ public:
|
||||
}}
|
||||
}
|
||||
|
||||
bool equals(const histo_data& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
|
||||
if(&a_from==this) return true;
|
||||
if(m_title!=a_from.m_title) return false;
|
||||
if(m_dimension!=a_from.m_dimension) return false;
|
||||
if(m_bin_number!=a_from.m_bin_number) return false;
|
||||
if(m_bin_entries!=a_from.m_bin_entries) return false;
|
||||
//if(!vequ(m_bin_entries,a_from.m_bin_entries)) return false;
|
||||
if(!vectors_are_equal(m_bin_Sw,a_from.m_bin_Sw,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_bin_Sw2,a_from.m_bin_Sw2,a_prec,a_fabs)) return false;
|
||||
if(!vecvecs_are_equal(m_bin_Sxw,a_from.m_bin_Sxw,a_prec,a_fabs)) return false;
|
||||
if(!vecvecs_are_equal(m_bin_Sx2w,a_from.m_bin_Sx2w,a_prec,a_fabs)) return false;
|
||||
if(m_axes!=a_from.m_axes) return false;
|
||||
if(!vectors_are_equal(m_in_range_plane_Sxyw,a_from.m_in_range_plane_Sxyw,a_prec,a_fabs)) return false;
|
||||
if(m_annotations!=a_from.m_annotations) return false;
|
||||
|
||||
if(m_all_entries!=a_from.m_all_entries) return false;
|
||||
if(m_in_range_entries!=a_from.m_in_range_entries) return false;
|
||||
|
||||
if(!numbers_are_equal(m_in_range_Sw,a_from.m_in_range_Sw,a_prec,a_fabs)) return false;
|
||||
if(!numbers_are_equal(m_in_range_Sw2,a_from.m_in_range_Sw2,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_in_range_Sxw,a_from.m_in_range_Sxw,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_in_range_Sx2w,a_from.m_in_range_Sx2w,a_prec,a_fabs)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool equals_TH(const histo_data& a_from,const TW& a_prec,TW(*a_fabs)(TW),bool a_cmp_bin_Sw2) const {
|
||||
// used to compare with an histo built from a TH stream out from a CERN-ROOT file.
|
||||
if(&a_from==this) return true;
|
||||
if(m_title!=a_from.m_title) return false;
|
||||
if(m_dimension!=a_from.m_dimension) return false;
|
||||
if(m_bin_number!=a_from.m_bin_number) return false;
|
||||
//if(m_bin_entries!=a_from.m_bin_entries) return false;
|
||||
if(!vectors_are_equal(m_bin_Sw,a_from.m_bin_Sw,a_prec,a_fabs)) return false;
|
||||
if(a_cmp_bin_Sw2) if(!vectors_are_equal(m_bin_Sw2,a_from.m_bin_Sw2,a_prec,a_fabs)) return false;
|
||||
//if(!vecvecs_are_equal(m_bin_Sxw,a_from.m_bin_Sxw,a_prec,a_fabs)) return false;
|
||||
//if(!vecvecs_are_equal(m_bin_Sx2w,a_from.m_bin_Sx2w,a_prec,a_fabs)) return false;
|
||||
if(m_axes!=a_from.m_axes) return false;
|
||||
if(!vectors_are_equal(m_in_range_plane_Sxyw,a_from.m_in_range_plane_Sxyw,a_prec,a_fabs)) return false;
|
||||
//if(m_annotations!=a_from.m_annotations) return false;
|
||||
|
||||
if(m_all_entries!=a_from.m_all_entries) return false;
|
||||
//if(m_in_range_entries!=a_from.m_in_range_entries) return false;
|
||||
|
||||
if(!numbers_are_equal(m_in_range_Sw,a_from.m_in_range_Sw,a_prec,a_fabs)) return false;
|
||||
if(!numbers_are_equal(m_in_range_Sw2,a_from.m_in_range_Sw2,a_prec,a_fabs)) return false;
|
||||
//if(!vectors_are_equal(m_in_range_Sxw,a_from.m_in_range_Sxw,a_prec,a_fabs)) return false;
|
||||
//if(!vectors_are_equal(m_in_range_Sx2w,a_from.m_in_range_Sx2w,a_prec,a_fabs)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
// General :
|
||||
std::string m_title;
|
||||
|
||||
@@ -0,0 +1,338 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_histo_htoc
|
||||
#define tools_histo_htoc
|
||||
|
||||
struct caxis_dui { //d=double, ui=unsigned int
|
||||
typedef double TC;
|
||||
typedef unsigned int TO;
|
||||
typedef unsigned int bn_t;
|
||||
|
||||
TO m_offset;
|
||||
bn_t m_number_of_bins;
|
||||
TC m_minimum_value;
|
||||
TC m_maximum_value;
|
||||
unsigned char m_fixed;
|
||||
TC m_bin_width;
|
||||
unsigned int m_number_of_edges;
|
||||
TC* m_edges; //[m_number_of_edges]
|
||||
};
|
||||
|
||||
struct chisto_duiuid {
|
||||
typedef double TC;
|
||||
typedef unsigned int TO;
|
||||
typedef unsigned int TN;
|
||||
typedef double TW;
|
||||
typedef unsigned int dim_t;
|
||||
|
||||
// General :
|
||||
char* m_title;
|
||||
dim_t m_dimension;
|
||||
// Bins :
|
||||
TO m_bin_number;
|
||||
TN* m_bin_entries; //[m_bin_number]
|
||||
TW* m_bin_Sw; //[m_bin_number]
|
||||
TW* m_bin_Sw2; //[m_bin_number]
|
||||
TC** m_bin_Sxw; //[m_bin_number][m_dimension]
|
||||
TC** m_bin_Sx2w; //[m_bin_number][m_dimension]
|
||||
// Axes :
|
||||
caxis_dui** m_axes; //[m_dimension]
|
||||
// etc :
|
||||
TC* m_in_range_plane_Sxyw; //(dim,size) (1,0) (2,1) (3,3)
|
||||
unsigned int m_number_of_annotations;
|
||||
char** m_annotations; //[m_number_of_annotations]
|
||||
// fast getters :
|
||||
TN m_all_entries; //used if reading from a ROOT file.
|
||||
TN m_in_range_entries;
|
||||
TW m_in_range_Sw;
|
||||
TW m_in_range_Sw2;
|
||||
TC* m_in_range_Sxw; //[m_dimension]
|
||||
TC* m_in_range_Sx2w; //[m_dimension]
|
||||
};
|
||||
|
||||
struct cprofile_duiuidd {
|
||||
typedef double TV;
|
||||
|
||||
chisto_duiuid m_histo;
|
||||
|
||||
unsigned char m_is_profile;
|
||||
TV* m_bin_Svw; //[m_bin_number]
|
||||
TV* m_bin_Sv2w; //[m_bin_number]
|
||||
unsigned char m_cut_v;
|
||||
TV m_min_v;
|
||||
TV m_max_v;
|
||||
};
|
||||
|
||||
#include "histo_data"
|
||||
|
||||
#include "../cstr"
|
||||
#include "../cmemT"
|
||||
#include "../vdata"
|
||||
#include "../forit"
|
||||
|
||||
namespace tools {
|
||||
namespace histo {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// hist_data to C struct ///////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline caxis_dui* caxis_dui_alloc(const axis<double,unsigned int>& a_axis) {
|
||||
caxis_dui* a_cp = cmem_alloc<caxis_dui>(1);
|
||||
if(!a_cp) return NULL;
|
||||
|
||||
caxis_dui& a_c = *a_cp;
|
||||
|
||||
typedef double TC;
|
||||
|
||||
a_c.m_offset = a_axis.m_offset;
|
||||
a_c.m_number_of_bins = a_axis.m_number_of_bins;
|
||||
a_c.m_minimum_value = a_axis.m_minimum_value;
|
||||
a_c.m_maximum_value = a_axis.m_maximum_value;
|
||||
a_c.m_fixed = a_axis.m_fixed?1:0;
|
||||
a_c.m_bin_width = a_axis.m_bin_width;
|
||||
a_c.m_number_of_edges = (unsigned int)a_axis.m_edges.size();
|
||||
a_c.m_edges = cmem_alloc_copy<TC>(vec_data(a_axis.m_edges),a_axis.m_edges.size());
|
||||
|
||||
return a_cp;
|
||||
}
|
||||
|
||||
inline void caxis_dui_free(caxis_dui*& a_cp) {
|
||||
if(!a_cp) return;
|
||||
caxis_dui& a_c = *a_cp;
|
||||
|
||||
cmem_free(a_c.m_edges);
|
||||
|
||||
a_c.m_offset = 0;
|
||||
a_c.m_number_of_bins = 0;
|
||||
a_c.m_minimum_value = 0;
|
||||
a_c.m_maximum_value = 0;
|
||||
a_c.m_fixed = 1;
|
||||
a_c.m_bin_width = 0;
|
||||
a_c.m_number_of_edges = 0;
|
||||
|
||||
cmem_free(a_cp);
|
||||
}
|
||||
|
||||
inline void chisto_duiuid_assign(chisto_duiuid& a_c,const histo_data<double,unsigned int,unsigned int,double>& a_hd) {
|
||||
typedef double TC;
|
||||
typedef unsigned int TN;
|
||||
typedef double TW;
|
||||
|
||||
a_c.m_title = str_dup(a_hd.m_title.c_str());
|
||||
a_c.m_dimension = a_hd.m_dimension;
|
||||
a_c.m_bin_number = a_hd.m_bin_number;
|
||||
a_c.m_bin_entries = cmem_alloc_copy<TN>(vec_data(a_hd.m_bin_entries),a_hd.m_bin_number);
|
||||
a_c.m_bin_Sw = cmem_alloc_copy<TW>(vec_data(a_hd.m_bin_Sw),a_hd.m_bin_number);
|
||||
a_c.m_bin_Sw2 = cmem_alloc_copy<TW>(vec_data(a_hd.m_bin_Sw2),a_hd.m_bin_number);
|
||||
|
||||
{a_c.m_bin_Sxw = cmem_alloc<TC*>(a_hd.m_bin_number);
|
||||
for(unsigned int ibin=0;ibin<a_hd.m_bin_number;ibin++) {
|
||||
a_c.m_bin_Sxw[ibin] = cmem_alloc_copy<TC>(vec_data(a_hd.m_bin_Sxw[ibin]),a_hd.m_dimension);
|
||||
}}
|
||||
{a_c.m_bin_Sx2w = cmem_alloc<TC*>(a_hd.m_bin_number);
|
||||
for(unsigned int ibin=0;ibin<a_hd.m_bin_number;ibin++) {
|
||||
a_c.m_bin_Sx2w[ibin] = cmem_alloc_copy<TC>(vec_data(a_hd.m_bin_Sx2w[ibin]),a_hd.m_dimension);
|
||||
}}
|
||||
|
||||
// Axes :
|
||||
{a_c.m_axes = cmem_alloc<caxis_dui*>(a_hd.m_dimension);
|
||||
for(unsigned int iaxis=0;iaxis<a_hd.m_dimension;iaxis++) {
|
||||
a_c.m_axes[iaxis] = caxis_dui_alloc(a_hd.m_axes[iaxis]);
|
||||
}}
|
||||
|
||||
// etc :
|
||||
a_c.m_in_range_plane_Sxyw = cmem_alloc_copy<TC>(vec_data(a_hd.m_in_range_plane_Sxyw),dim_planes(a_hd.m_dimension));
|
||||
{a_c.m_number_of_annotations = (unsigned int)a_hd.m_annotations.size();
|
||||
a_c.m_annotations = cmem_alloc<char*>(2*a_hd.m_annotations.size());
|
||||
unsigned int index = 0;
|
||||
tools_mforcit(std::string,std::string,a_hd.m_annotations,it) {
|
||||
a_c.m_annotations[index] = str_dup((*it).first.c_str());index++;
|
||||
a_c.m_annotations[index] = str_dup((*it).second.c_str());index++;
|
||||
}}
|
||||
// fast getters :
|
||||
a_c.m_all_entries = a_hd.m_all_entries;
|
||||
a_c.m_in_range_entries = a_hd.m_in_range_entries;
|
||||
a_c.m_in_range_Sw = a_hd.m_in_range_Sw;
|
||||
a_c.m_in_range_Sw2 = a_hd.m_in_range_Sw2;
|
||||
a_c.m_in_range_Sxw = cmem_alloc_copy<TC>(vec_data(a_hd.m_in_range_Sxw),a_hd.m_dimension);
|
||||
a_c.m_in_range_Sx2w = cmem_alloc_copy<TC>(vec_data(a_hd.m_in_range_Sx2w),a_hd.m_dimension);
|
||||
|
||||
//FIXME : should check all sub pointers.
|
||||
//if(to_del {cmem_free(a_cp);return NULL;}
|
||||
}
|
||||
|
||||
inline chisto_duiuid* chisto_duiuid_alloc(const histo_data<double,unsigned int,unsigned int,double>& a_hd) {
|
||||
chisto_duiuid* a_cp = cmem_alloc<chisto_duiuid>(1);
|
||||
if(!a_cp) return NULL;
|
||||
chisto_duiuid_assign(*a_cp,a_hd);
|
||||
return a_cp;
|
||||
}
|
||||
|
||||
inline void chisto_duiuid_clear(chisto_duiuid& a_c) {
|
||||
str_del(a_c.m_title);
|
||||
|
||||
cmem_free(a_c.m_bin_entries);
|
||||
cmem_free(a_c.m_bin_Sw);
|
||||
cmem_free(a_c.m_bin_Sw2);
|
||||
|
||||
{for(unsigned int ibin=0;ibin<a_c.m_bin_number;ibin++) cmem_free(a_c.m_bin_Sxw[ibin]);
|
||||
cmem_free(a_c.m_bin_Sxw);}
|
||||
{for(unsigned int ibin=0;ibin<a_c.m_bin_number;ibin++) cmem_free(a_c.m_bin_Sx2w[ibin]);
|
||||
cmem_free(a_c.m_bin_Sx2w);}
|
||||
|
||||
cmem_free(a_c.m_in_range_plane_Sxyw);
|
||||
|
||||
{for(unsigned int iaxis=0;iaxis<a_c.m_dimension;iaxis++) caxis_dui_free(a_c.m_axes[iaxis]);
|
||||
cmem_free(a_c.m_axes);}
|
||||
|
||||
{for(unsigned int i=0;i<(2*a_c.m_number_of_annotations);i++) str_del(a_c.m_annotations[i]);
|
||||
cmem_free(a_c.m_annotations);}
|
||||
|
||||
cmem_free(a_c.m_in_range_Sxw);
|
||||
cmem_free(a_c.m_in_range_Sx2w);
|
||||
|
||||
a_c.m_dimension = 0;
|
||||
a_c.m_bin_number = 0;
|
||||
a_c.m_number_of_annotations = 0;
|
||||
|
||||
a_c.m_all_entries = 0;
|
||||
a_c.m_in_range_entries = 0;
|
||||
a_c.m_in_range_Sw = 0;
|
||||
a_c.m_in_range_Sw2 = 0;
|
||||
}
|
||||
|
||||
inline void chisto_duiuid_free(chisto_duiuid*& a_cp) {
|
||||
if(!a_cp) return;
|
||||
chisto_duiuid_clear(*a_cp);
|
||||
cmem_free(a_cp);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// C struct to hist_data ///////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T>
|
||||
inline void vec_assign(std::vector<T>& a_v,unsigned int a_number,const T* a_c) {
|
||||
a_v.resize(a_number);
|
||||
for(unsigned int i=0;i<a_number;i++) a_v[i] = a_c[i];
|
||||
}
|
||||
|
||||
inline void axis_dui_assign(axis<double,unsigned int>& a_axis,const caxis_dui& a_c) {
|
||||
a_axis.m_offset = a_c.m_offset;
|
||||
a_axis.m_number_of_bins = a_c.m_number_of_bins;
|
||||
a_axis.m_minimum_value = a_c.m_minimum_value;
|
||||
a_axis.m_maximum_value = a_c.m_maximum_value;
|
||||
a_axis.m_fixed = a_c.m_fixed==1?true:false;
|
||||
a_axis.m_bin_width = a_c.m_bin_width;
|
||||
vec_assign(a_axis.m_edges,a_c.m_number_of_edges,a_c.m_edges);
|
||||
}
|
||||
|
||||
inline void histo_data_duiuid_assign(histo_data<double,unsigned int,unsigned int,double>& a_hd,const chisto_duiuid& a_c) {
|
||||
a_hd.m_title = std::string(a_c.m_title);
|
||||
a_hd.m_dimension = a_c.m_dimension;
|
||||
a_hd.m_bin_number = a_c.m_bin_number;
|
||||
vec_assign(a_hd.m_bin_entries,a_c.m_bin_number,a_c.m_bin_entries);
|
||||
vec_assign(a_hd.m_bin_Sw,a_c.m_bin_number,a_c.m_bin_Sw);
|
||||
vec_assign(a_hd.m_bin_Sw2,a_c.m_bin_number,a_c.m_bin_Sw2);
|
||||
|
||||
{a_hd.m_bin_Sxw.resize(a_c.m_bin_number);
|
||||
for(unsigned int ibin=0;ibin<a_c.m_bin_number;ibin++) {
|
||||
vec_assign(a_hd.m_bin_Sxw[ibin],a_c.m_dimension,a_c.m_bin_Sxw[ibin]);
|
||||
}}
|
||||
{a_hd.m_bin_Sx2w.resize(a_c.m_bin_number);
|
||||
for(unsigned int ibin=0;ibin<a_c.m_bin_number;ibin++) {
|
||||
vec_assign(a_hd.m_bin_Sx2w[ibin],a_c.m_dimension,a_c.m_bin_Sx2w[ibin]);
|
||||
}}
|
||||
|
||||
{a_hd.m_axes.resize(a_c.m_dimension);
|
||||
for(unsigned int iaxis=0;iaxis<a_c.m_dimension;iaxis++) {
|
||||
axis_dui_assign(a_hd.m_axes[iaxis],*(a_c.m_axes[iaxis]));
|
||||
}}
|
||||
vec_assign(a_hd.m_in_range_plane_Sxyw,dim_planes(a_c.m_dimension),a_c.m_in_range_plane_Sxyw);
|
||||
|
||||
{a_hd.m_annotations.clear();
|
||||
for(unsigned int i=0;i<a_c.m_number_of_annotations;i++) {
|
||||
a_hd.m_annotations[a_c.m_annotations[2*i+0]] = a_c.m_annotations[2*i+1];
|
||||
}}
|
||||
|
||||
a_hd.m_all_entries = a_c.m_all_entries;
|
||||
a_hd.m_in_range_entries = a_c.m_in_range_entries;
|
||||
a_hd.m_in_range_Sw = a_c.m_in_range_Sw;
|
||||
a_hd.m_in_range_Sw2 = a_c.m_in_range_Sw2;
|
||||
vec_assign(a_hd.m_in_range_Sxw,a_c.m_dimension,a_c.m_in_range_Sxw);
|
||||
vec_assign(a_hd.m_in_range_Sx2w,a_c.m_dimension,a_c.m_in_range_Sx2w);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#include "profile_data"
|
||||
|
||||
namespace tools {
|
||||
namespace histo {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// profile_data to C struct ////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline cprofile_duiuidd* cprofile_duiuidd_alloc(const profile_data<double,unsigned int,unsigned int,double,double>& a_pd) {
|
||||
cprofile_duiuidd* a_cp = cmem_alloc<cprofile_duiuidd>(1);
|
||||
if(!a_cp) return NULL;
|
||||
|
||||
cprofile_duiuidd& a_c = *a_cp;
|
||||
|
||||
chisto_duiuid_assign(a_c.m_histo,a_pd);
|
||||
|
||||
typedef double TV;
|
||||
|
||||
// profile part :
|
||||
a_c.m_is_profile = a_pd.m_is_profile?1:0;
|
||||
a_c.m_bin_Svw = cmem_alloc_copy<TV>(vec_data(a_pd.m_bin_Svw),a_pd.m_bin_number);
|
||||
a_c.m_bin_Sv2w = cmem_alloc_copy<TV>(vec_data(a_pd.m_bin_Sv2w),a_pd.m_bin_number);
|
||||
a_c.m_cut_v = a_pd.m_cut_v?1:0;
|
||||
a_c.m_min_v = a_pd.m_min_v;
|
||||
a_c.m_max_v = a_pd.m_max_v;
|
||||
|
||||
return a_cp;
|
||||
}
|
||||
|
||||
inline void cprofile_duiuidd_free(cprofile_duiuidd*& a_cp) {
|
||||
if(!a_cp) return;
|
||||
|
||||
cprofile_duiuidd& a_c = *a_cp;
|
||||
|
||||
chisto_duiuid_clear(a_c.m_histo);
|
||||
|
||||
cmem_free(a_c.m_bin_Svw);
|
||||
cmem_free(a_c.m_bin_Sv2w);
|
||||
|
||||
a_c.m_is_profile = 1;
|
||||
a_c.m_cut_v = 0;
|
||||
a_c.m_min_v = 0;
|
||||
a_c.m_max_v = 0;
|
||||
|
||||
cmem_free(a_cp);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/// C struct to profile_data ////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void profile_data_duiuidd_assign(profile_data<double,unsigned int,unsigned int,double,double>& a_pd,const cprofile_duiuidd& a_c) {
|
||||
histo_data_duiuid_assign(a_pd,a_c.m_histo);
|
||||
a_pd.m_is_profile = a_c.m_is_profile==1?true:false;
|
||||
vec_assign(a_pd.m_bin_Svw,a_c.m_histo.m_bin_number,a_c.m_bin_Svw);
|
||||
vec_assign(a_pd.m_bin_Sv2w,a_c.m_histo.m_bin_number,a_c.m_bin_Sv2w);
|
||||
a_pd.m_cut_v = a_c.m_cut_v==1?true:false;
|
||||
a_pd.m_min_v = a_c.m_min_v;
|
||||
a_pd.m_max_v = a_c.m_max_v;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,13 +23,31 @@ class p1 : public b1<TC,TO,TN,TW,TH> {
|
||||
public:
|
||||
typedef profile_data<TC,TO,TN,TW,TV> pd_t;
|
||||
typedef typename parent::bn_t bn_t;
|
||||
typedef histo::axis<TC,TO> axis_t;
|
||||
typedef typename parent::axis_t axis_t;
|
||||
typedef std::vector<TV> vs_t;
|
||||
protected:
|
||||
virtual TH get_bin_height(TO a_offset) const {
|
||||
return (parent::m_bin_Sw[a_offset] ? (m_bin_Svw[a_offset]/parent::m_bin_Sw[a_offset]):0);
|
||||
}
|
||||
public:
|
||||
bool equals(const p1& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
|
||||
if(!parent::equals(a_from,a_prec,a_fabs)) return false;
|
||||
if(m_cut_v!=a_from.m_cut_v) return false;
|
||||
if(!numbers_are_equal(m_min_v,a_from.m_min_v,a_prec,a_fabs)) return false;
|
||||
if(!numbers_are_equal(m_max_v,a_from.m_max_v,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_bin_Svw,a_from.m_bin_Svw,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_bin_Sv2w,a_from.m_bin_Sv2w,a_prec,a_fabs)) return false;
|
||||
return true;
|
||||
}
|
||||
bool equals_TH(const p1& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
|
||||
if(!parent::equals_TH(a_from,a_prec,a_fabs,false)) return false;
|
||||
if(m_cut_v!=a_from.m_cut_v) return false;
|
||||
if(!numbers_are_equal(m_min_v,a_from.m_min_v,a_prec,a_fabs)) return false;
|
||||
if(!numbers_are_equal(m_max_v,a_from.m_max_v,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_bin_Svw,a_from.m_bin_Svw,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_bin_Sv2w,a_from.m_bin_Sv2w,a_prec,a_fabs)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual TH bin_error(int aI) const { //TH should be the same as TV
|
||||
TO offset;
|
||||
|
||||
@@ -18,6 +18,8 @@ public:
|
||||
}
|
||||
const std::string& s_cls() const {return s_class();}
|
||||
public:
|
||||
p1d():parent("",10,0,1){} //for I/O when reading.
|
||||
|
||||
p1d(const std::string& a_title,unsigned int aXnumber,double aXmin,double aXmax)
|
||||
:parent(a_title,aXnumber,aXmin,aXmax)
|
||||
{}
|
||||
|
||||
@@ -22,6 +22,24 @@ protected:
|
||||
return (parent::m_bin_Sw[a_offset] ? (m_bin_Svw[a_offset]/parent::m_bin_Sw[a_offset]):0);
|
||||
}
|
||||
public:
|
||||
bool equals(const p2& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
|
||||
if(!parent::equals(a_from,a_prec,a_fabs)) return false;
|
||||
if(m_cut_v!=a_from.m_cut_v) return false;
|
||||
if(!numbers_are_equal(m_min_v,a_from.m_min_v,a_prec,a_fabs)) return false;
|
||||
if(!numbers_are_equal(m_max_v,a_from.m_max_v,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_bin_Svw,a_from.m_bin_Svw,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_bin_Sv2w,a_from.m_bin_Sv2w,a_prec,a_fabs)) return false;
|
||||
return true;
|
||||
}
|
||||
bool equals_TH(const p2& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
|
||||
if(!parent::equals_TH(a_from,a_prec,a_fabs,false)) return false;
|
||||
if(m_cut_v!=a_from.m_cut_v) return false;
|
||||
if(!numbers_are_equal(m_min_v,a_from.m_min_v,a_prec,a_fabs)) return false;
|
||||
if(!numbers_are_equal(m_max_v,a_from.m_max_v,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_bin_Svw,a_from.m_bin_Svw,a_prec,a_fabs)) return false;
|
||||
if(!vectors_are_equal(m_bin_Sv2w,a_from.m_bin_Sv2w,a_prec,a_fabs)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual TH bin_error(int aI,int aJ) const { //TH should be the same as TV
|
||||
TO offset;
|
||||
|
||||
@@ -18,6 +18,8 @@ public:
|
||||
}
|
||||
const std::string& s_cls() const {return s_class();}
|
||||
public:
|
||||
p2d():parent("",10,0,1,10,0,1){} //for I/O when reading.
|
||||
|
||||
p2d(const std::string& a_title,
|
||||
unsigned int aXnumber,double aXmin,double aXmax,
|
||||
unsigned int aYnumber,double aYmin,double aYmax)
|
||||
|
||||
@@ -102,8 +102,8 @@ class axis {
|
||||
static double TMath_ATan2(double y, double x) {
|
||||
if (x != 0) return ::atan2(y, x);
|
||||
if (y == 0) return 0;
|
||||
if (y > 0) return tools::half_pi();
|
||||
else return -tools::half_pi();
|
||||
if (y > 0) return half_pi();
|
||||
else return -half_pi();
|
||||
}
|
||||
|
||||
//static short TMath_Abs(short d) { return (d >= 0) ? d : -d; }
|
||||
@@ -352,7 +352,7 @@ public:
|
||||
double rangeOffset = 0;
|
||||
|
||||
double epsilon = 1e-5;
|
||||
const double kPI = tools::pi(); //GB
|
||||
const double kPI = pi(); //GB
|
||||
double textSize = 0.05; //GB
|
||||
short textAlign = 11; //GB
|
||||
BinWidth = 0; //GB
|
||||
@@ -528,9 +528,9 @@ public:
|
||||
int N1A = ndiv%100;
|
||||
int N2A = (ndiv%10000 - N1A)/100;
|
||||
int N3A = ndiv/10000;
|
||||
int NN3 = tools::mx(N3A,1);
|
||||
int NN2 = tools::mx(N2A,1)*NN3;
|
||||
int NN1 = tools::mx(N1A,1)*NN2+1;
|
||||
int NN3 = mx<int>(N3A,1);
|
||||
int NN2 = mx<int>(N2A,1)*NN3;
|
||||
int NN1 = mx<int>(N1A,1)*NN2+1;
|
||||
int Nticks= NN1;
|
||||
|
||||
// Axis bining optimization is ignored if:
|
||||
@@ -616,9 +616,9 @@ public:
|
||||
N1Aold = N1A;
|
||||
NN1old = NN1;
|
||||
N1A = nbins;
|
||||
NN3 = tools::mx(NB3,1);
|
||||
NN2 = tools::mx(NB2,1)*NN3;
|
||||
NN1 = tools::mx(N1A,1)*NN2+1;
|
||||
NN3 = mx<int>(NB3,1);
|
||||
NN2 = mx<int>(NB2,1)*NN3;
|
||||
NN1 = mx<int>(N1A,1)*NN2+1;
|
||||
Nticks = NN1;
|
||||
}
|
||||
|
||||
@@ -1174,7 +1174,7 @@ public:
|
||||
NEXE = 0;
|
||||
bool FLEXPO = false;
|
||||
bool FLEXNE = false;
|
||||
WW = tools::mx(TMath_Abs(wmin),TMath_Abs(wmax));
|
||||
WW = mx<double>(TMath_Abs(wmin),TMath_Abs(wmax));
|
||||
|
||||
// First case : (wmax-wmin)/N1A less than 0.001
|
||||
// 0.001 fMaxDigits of 5 (fMaxDigits) characters).
|
||||
@@ -1246,10 +1246,10 @@ public:
|
||||
}
|
||||
|
||||
IF2 = NA;
|
||||
IF1 = tools::mx(NF+NA,maxDigits)+1;
|
||||
IF1 = mx<int>(NF+NA,maxDigits)+1;
|
||||
L110:
|
||||
if (tools::mn(wmin,wmax) < 0)IF1 = IF1+1;
|
||||
IF1 = tools::mn(IF1,32);
|
||||
if (mn<double>(wmin,wmax) < 0)IF1 = IF1+1;
|
||||
IF1 = mn<int>(IF1,32);
|
||||
|
||||
// In some cases, IF1 and IF2 are too small....
|
||||
while (DWlabel < ::pow(10.,-IF2)) {
|
||||
@@ -1877,12 +1877,12 @@ private:
|
||||
int OptionTime;
|
||||
SETOPT(aCHOPT,'t',OptionTime);
|
||||
|
||||
double AL = tools::mn(A1,A2);
|
||||
double AH = tools::mx(A1,A2);
|
||||
double AL = mn<double>(A1,A2);
|
||||
double AH = mx<double>(A1,A2);
|
||||
if (AL == AH) AH = AL+1;
|
||||
// if nold == -1 , program uses binwidth input from calling routine
|
||||
if (nold == -1 && BinWidth > 0 ) goto L90;
|
||||
ntemp = tools::mx(nold,2);
|
||||
ntemp = (int)mx<double>(nold,2);
|
||||
if (ntemp < 1) ntemp = 1;
|
||||
|
||||
L20:
|
||||
|
||||
@@ -375,8 +375,8 @@ public:
|
||||
}
|
||||
{for(unsigned int ipix=0;ipix<m_n;ipix++) pixels[ipix] = 0;}
|
||||
|
||||
unsigned int wfac = double(m_w)/double(a_w);
|
||||
unsigned int hfac = double(m_h)/double(a_h);
|
||||
unsigned int wfac = (unsigned int)(double(m_w)/double(a_w));
|
||||
unsigned int hfac = (unsigned int)(double(m_h)/double(a_h));
|
||||
if(!wfac) wfac = 1;
|
||||
if(!hfac) hfac = 1;
|
||||
|
||||
@@ -474,8 +474,8 @@ public:
|
||||
}
|
||||
|
||||
// 012345
|
||||
unsigned int rw = tools::mn<unsigned int>(m_w-a_sx,a_sw);
|
||||
unsigned int rh = tools::mn<unsigned int>(m_h-a_sy,a_sh);
|
||||
unsigned int rw = min_of<unsigned int>(m_w-a_sx,a_sw);
|
||||
unsigned int rh = min_of<unsigned int>(m_h-a_sy,a_sh);
|
||||
unsigned int sz = rh*rw*m_n;
|
||||
if(!sz) {
|
||||
a_res.make_empty();
|
||||
|
||||
@@ -15,9 +15,13 @@ class impi {
|
||||
public:
|
||||
virtual ~impi(){}
|
||||
public:
|
||||
virtual bool pack(char) = 0;
|
||||
virtual bool pack(short) = 0;
|
||||
virtual bool pack(int) = 0;
|
||||
virtual bool pack(unsigned int) = 0;
|
||||
virtual bool pack(uint64) = 0;
|
||||
virtual bool pack(int64) = 0;
|
||||
virtual bool pack(float) = 0;
|
||||
virtual bool pack(double) = 0;
|
||||
virtual bool bpack(bool) = 0;
|
||||
virtual bool spack(const std::string&) = 0;
|
||||
@@ -27,9 +31,13 @@ public:
|
||||
virtual bool pack(uint32,const char*) = 0;
|
||||
virtual bool pack(uint32,const int*) = 0;
|
||||
|
||||
virtual bool unpack(char&) = 0;
|
||||
virtual bool unpack(short&) = 0;
|
||||
virtual bool unpack(int&) = 0;
|
||||
virtual bool unpack(unsigned int&) = 0;
|
||||
virtual bool unpack(uint64&) = 0;
|
||||
virtual bool unpack(int64&) = 0;
|
||||
virtual bool unpack(float&) = 0;
|
||||
virtual bool unpack(double&) = 0;
|
||||
virtual bool bunpack(bool&) = 0;
|
||||
virtual bool sunpack(std::string&) = 0;
|
||||
@@ -39,9 +47,11 @@ public:
|
||||
virtual bool unpack(uint32&,char*&) = 0;
|
||||
virtual bool unpack(uint32&,int*&) = 0;
|
||||
|
||||
// for tools::mpi::pntuple :
|
||||
virtual void pack_reset() = 0;
|
||||
virtual bool send_buffer(int,int) = 0;
|
||||
|
||||
virtual bool wait_buffer(int rank,int src,int tag,int& probe_src,bool verbose = false) = 0;
|
||||
virtual bool wait_buffer(int rank,int tag,int& probe_src,bool verbose = false) = 0; //MPI_ANY_SOURCE.
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_ival_func
|
||||
#define tools_ival_func
|
||||
|
||||
#include "value"
|
||||
|
||||
namespace tools {
|
||||
|
||||
class ival_func {
|
||||
public:
|
||||
virtual ~ival_func() {}
|
||||
public:
|
||||
virtual void* cast(const std::string&) const = 0;
|
||||
public:
|
||||
virtual const std::string& name() const = 0;
|
||||
virtual size_t number_of_arguments() const = 0;
|
||||
typedef std::vector<value> args;
|
||||
virtual bool eval(const args&,value&,std::string&) = 0;
|
||||
virtual ival_func* copy() const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -258,26 +258,25 @@ public:\
|
||||
bool is_proportional_prec(const TOOLS_MAT_CLASS& a_right,const PREC& a_prec,PREC(*a_fabs)(const T&),T& a_factor) const {\
|
||||
/* If true, then : a_right = a_factor * this.*/\
|
||||
if(this==&a_right) {a_factor=T(1);return true;}\
|
||||
T _zero = zero();\
|
||||
a_factor = _zero;\
|
||||
a_factor = zero();\
|
||||
if(dimension()!=a_right.dimension()) return false;\
|
||||
T* lp = (T*)m_vec;\
|
||||
T* rp = (T*)a_right.m_vec;\
|
||||
bool first = true;\
|
||||
size_t _data_size = data_size();\
|
||||
for(size_t i=0;i<_data_size;i++,lp++,rp++) {\
|
||||
if( numbers_are_equals(*lp,_zero,a_prec,a_fabs) && numbers_are_equals(*rp,_zero,a_prec,a_fabs) ) {\
|
||||
if( is_zero(*lp,a_prec,a_fabs) && is_zero(*rp,a_prec,a_fabs) ) {\
|
||||
continue;\
|
||||
} else if( !numbers_are_equals(*lp,_zero,a_prec,a_fabs) && numbers_are_equals(*rp,_zero,a_prec,a_fabs) ) {\
|
||||
} else if( !is_zero(*lp,a_prec,a_fabs) && is_zero(*rp,a_prec,a_fabs) ) {\
|
||||
return false;\
|
||||
} else if( numbers_are_equals(*lp,_zero,a_prec,a_fabs) && !numbers_are_equals(*rp,_zero,a_prec,a_fabs) ) {\
|
||||
} else if( is_zero(*lp,a_prec,a_fabs) && !is_zero(*rp,a_prec,a_fabs) ) {\
|
||||
return false;\
|
||||
} else {\
|
||||
if(first) {\
|
||||
a_factor = (*rp)/(*lp);\
|
||||
first = false;\
|
||||
} else {\
|
||||
if(!numbers_are_equals((*lp)*a_factor,*rp,a_prec,a_fabs)) return false;\
|
||||
if(!numbers_are_equal((*lp)*a_factor,*rp,a_prec,a_fabs)) return false;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
@@ -286,11 +285,10 @@ public:\
|
||||
\
|
||||
template <class PREC>\
|
||||
bool is_diagonal_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
|
||||
T _zero = zero();\
|
||||
unsigned int _D = dimension();\
|
||||
for(unsigned int r=0;r<_D;r++) {\
|
||||
for(unsigned int c=0;c<_D;c++) {\
|
||||
if(c!=r) {if(!numbers_are_equals(value(r,c),_zero,a_prec,a_fabs)) return false;}\
|
||||
if(c!=r) {if(!is_zero(value(r,c),a_prec,a_fabs)) return false;}\
|
||||
}\
|
||||
}\
|
||||
return true;\
|
||||
@@ -357,6 +355,21 @@ public:\
|
||||
}\
|
||||
return true;\
|
||||
}\
|
||||
\
|
||||
template <class PREC>\
|
||||
bool is_antisymmetric_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
|
||||
unsigned int _D = dimension();\
|
||||
{for(unsigned int r=0;r<_D;r++) {\
|
||||
if(a_fabs(value(r,r))>=a_prec) return false;\
|
||||
}}\
|
||||
for(unsigned int r=0;r<_D;r++) {\
|
||||
for(unsigned int c=(r+1);c<_D;c++) {\
|
||||
T diff = value(r,c)-minus_one()*value(c,r);\
|
||||
if(a_fabs(diff)>=a_prec) return false;\
|
||||
}\
|
||||
}\
|
||||
return true;\
|
||||
}\
|
||||
\
|
||||
void symmetric_part(TOOLS_MAT_CLASS& a_res) const {\
|
||||
a_res = *this;\
|
||||
@@ -373,7 +386,49 @@ public:\
|
||||
a_res.multiply(one()/two());\
|
||||
}\
|
||||
\
|
||||
T determinant(unsigned int a_tmp_rs[],unsigned int a_tmp_cs[]) const { /*[rord=dim-1]*/ \
|
||||
template <class PREC>\
|
||||
bool is_block_UL_DR(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
|
||||
/* Look if even dim matrix is of the form : |X 0|\
|
||||
|0 Y|*/\
|
||||
unsigned int _D = dimension();\
|
||||
unsigned int _D_2 = _D/2;\
|
||||
/*if(2*__D_2!=_D) return false;*/\
|
||||
for(unsigned int r=0;r<_D_2;r++) {\
|
||||
for(unsigned int c=_D_2;c<_D;c++) {\
|
||||
if(a_fabs(value(r,c))>=a_prec) return false;\
|
||||
}\
|
||||
}\
|
||||
for(unsigned int r=_D_2;r<_D;r++) {\
|
||||
for(unsigned int c=0;c<_D_2;c++) {\
|
||||
if(a_fabs(value(r,c))>=a_prec) return false;\
|
||||
}\
|
||||
}\
|
||||
return true;\
|
||||
}\
|
||||
\
|
||||
template <class PREC>\
|
||||
bool is_block_UR_DL(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
|
||||
/* Look if even dim matrix is of the form : |0 X|\
|
||||
|Y 0|*/\
|
||||
unsigned int _D = dimension();\
|
||||
unsigned int _D_2 = _D/2;\
|
||||
/*if(2*__D_2!=_D) return false;*/\
|
||||
for(unsigned int r=0;r<_D_2;r++) {\
|
||||
for(unsigned int c=0;c<_D_2;c++) {\
|
||||
if(a_fabs(value(r,c))>=a_prec) return false;\
|
||||
}\
|
||||
}\
|
||||
for(unsigned int r=_D_2;r<_D;r++) {\
|
||||
for(unsigned int c=_D_2;c<_D;c++) {\
|
||||
if(a_fabs(value(r,c))>=a_prec) return false;\
|
||||
}\
|
||||
}\
|
||||
return true;\
|
||||
}\
|
||||
\
|
||||
template <class PREC>\
|
||||
T determinant_prec(unsigned int a_tmp_rs[],unsigned int a_tmp_cs[], /*[rord=dim-1]*/\
|
||||
const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
|
||||
unsigned int ord = dimension();\
|
||||
if(ord==0) {\
|
||||
return zero();\
|
||||
@@ -381,27 +436,27 @@ public:\
|
||||
return *m_vec;\
|
||||
} else if(ord==2) {\
|
||||
T v00 = *m_vec;\
|
||||
T v01 = *(m_vec+ord);\
|
||||
T v10 = *(m_vec+1);\
|
||||
T v11 = *(m_vec+1+ord);\
|
||||
T v01 = *(m_vec+2);\
|
||||
T v11 = *(m_vec+3);\
|
||||
return (v00 * v11 - v10 * v01);\
|
||||
} else if(ord==3) {\
|
||||
/* 00 01 02 \
|
||||
10 11 12 \
|
||||
20 21 22 \
|
||||
*/\
|
||||
T v01 = *(m_vec+ord);\
|
||||
T v02 = *(m_vec+2*ord);\
|
||||
T v11 = *(m_vec+1+ord);\
|
||||
T v12 = *(m_vec+1+2*ord);\
|
||||
T v21 = *(m_vec+2+ord);\
|
||||
T v22 = *(m_vec+2+2*ord);\
|
||||
T cof_00 = v11 * v22 - v21 * v12;\
|
||||
T cof_10 = v01 * v22 - v21 * v02;\
|
||||
T cof_20 = v01 * v12 - v11 * v02;\
|
||||
T v00 = *m_vec;\
|
||||
T v10 = *(m_vec+1);\
|
||||
T v20 = *(m_vec+2);\
|
||||
T v01 = *(m_vec+3);\
|
||||
T v11 = *(m_vec+4);\
|
||||
T v21 = *(m_vec+5);\
|
||||
T v02 = *(m_vec+6);\
|
||||
T v12 = *(m_vec+7);\
|
||||
T v22 = *(m_vec+8);\
|
||||
T cof_00 = v11 * v22 - v21 * v12;\
|
||||
T cof_10 = v01 * v22 - v21 * v02;\
|
||||
T cof_20 = v01 * v12 - v11 * v02;\
|
||||
return (v00*cof_00-v10*cof_10+v20*cof_20);\
|
||||
}\
|
||||
\
|
||||
@@ -418,8 +473,8 @@ public:\
|
||||
for(unsigned int r=0;r<ord;r++) {\
|
||||
if(r>=1) a_tmp_rs[r-1] = r-1;\
|
||||
v_rc = value(r,c);\
|
||||
if(v_rc!=zero()) {\
|
||||
T subdet = sub_determinant(rord,a_tmp_rs,a_tmp_cs);\
|
||||
if(!is_zero(v_rc,a_prec,a_fabs)) {\
|
||||
T subdet = sub_determinant_prec(rord,a_tmp_rs,a_tmp_cs,a_prec,a_fabs);\
|
||||
if(sg) \
|
||||
det += v_rc * subdet;\
|
||||
else\
|
||||
@@ -430,6 +485,10 @@ public:\
|
||||
\
|
||||
return det;\
|
||||
}\
|
||||
\
|
||||
T determinant(unsigned int a_tmp_rs[],unsigned int a_tmp_cs[]) const { /*[rord=dim-1]*/ \
|
||||
return determinant_prec<double>(a_tmp_rs,a_tmp_cs,0,zero_fabs);\
|
||||
}\
|
||||
\
|
||||
T determinant() const {\
|
||||
unsigned int ord = dimension();\
|
||||
@@ -439,23 +498,27 @@ public:\
|
||||
return *m_vec;\
|
||||
} else if(ord==2) {\
|
||||
T v00 = *m_vec;\
|
||||
T v01 = *(m_vec+ord);\
|
||||
T v10 = *(m_vec+1);\
|
||||
T v11 = *(m_vec+1+ord);\
|
||||
T v01 = *(m_vec+2);\
|
||||
T v11 = *(m_vec+3);\
|
||||
return (v00 * v11 - v10 * v01);\
|
||||
} else if(ord==3) {\
|
||||
T v01 = *(m_vec+ord);\
|
||||
T v02 = *(m_vec+2*ord);\
|
||||
T v11 = *(m_vec+1+ord);\
|
||||
T v12 = *(m_vec+1+2*ord);\
|
||||
T v21 = *(m_vec+2+ord);\
|
||||
T v22 = *(m_vec+2+2*ord);\
|
||||
T cof_00 = v11 * v22 - v21 * v12;\
|
||||
T cof_10 = v01 * v22 - v21 * v02;\
|
||||
T cof_20 = v01 * v12 - v11 * v02;\
|
||||
/* 00 01 02 \
|
||||
10 11 12 \
|
||||
20 21 22 \
|
||||
*/\
|
||||
T v00 = *m_vec;\
|
||||
T v10 = *(m_vec+1);\
|
||||
T v20 = *(m_vec+2);\
|
||||
T v01 = *(m_vec+3);\
|
||||
T v11 = *(m_vec+4);\
|
||||
T v21 = *(m_vec+5);\
|
||||
T v02 = *(m_vec+6);\
|
||||
T v12 = *(m_vec+7);\
|
||||
T v22 = *(m_vec+8);\
|
||||
T cof_00 = v11 * v22 - v21 * v12;\
|
||||
T cof_10 = v01 * v22 - v21 * v02;\
|
||||
T cof_20 = v01 * v12 - v11 * v02;\
|
||||
return (v00*cof_00-v10*cof_10+v20*cof_20);\
|
||||
}\
|
||||
unsigned int rord = ord-1;\
|
||||
@@ -467,73 +530,200 @@ public:\
|
||||
return det;\
|
||||
}\
|
||||
\
|
||||
bool invert(TOOLS_MAT_CLASS& a_res) const {\
|
||||
/*Generic invertion method.*/\
|
||||
template <class PREC>\
|
||||
bool invert_prec(TOOLS_MAT_CLASS& a_res,\
|
||||
unsigned int a_tmp_rs[],unsigned int a_tmp_cs[], /*[rord=dim-1]*/\
|
||||
const PREC& a_prec,PREC(*a_fabs)(const T&) /*for det=?zero*/ \
|
||||
) const { \
|
||||
unsigned int ord = dimension();\
|
||||
if(ord==0) return true;\
|
||||
\
|
||||
if(ord==1) {\
|
||||
T v = value(0,0);\
|
||||
if(v==zero()) return false;\
|
||||
a_res.set_value(0,0,one()/v);\
|
||||
T det = value(0,0);\
|
||||
if(is_zero(det,a_prec,a_fabs)) return false;\
|
||||
a_res.set_value(0,0,one()/det);\
|
||||
return true;\
|
||||
} else if(ord==2) {\
|
||||
T v00 = *m_vec;\
|
||||
T v10 = *(m_vec+1);\
|
||||
T v01 = *(m_vec+2);\
|
||||
T v11 = *(m_vec+3);\
|
||||
T det = (v00 * v11 - v10 * v01);\
|
||||
if(is_zero(det,a_prec,a_fabs)) return false;\
|
||||
a_res.set_value(0,0,v11/det);\
|
||||
a_res.set_value(1,1,v00/det);\
|
||||
a_res.set_value(0,1,minus_one()*v01/det);\
|
||||
a_res.set_value(1,0,minus_one()*v10/det);\
|
||||
return true;\
|
||||
} else if(ord==3) {\
|
||||
/* 00 01 02 \
|
||||
10 11 12 \
|
||||
20 21 22 \
|
||||
*/\
|
||||
T v00 = *m_vec;\
|
||||
T v10 = *(m_vec+1);\
|
||||
T v20 = *(m_vec+2);\
|
||||
T v01 = *(m_vec+3);\
|
||||
T v11 = *(m_vec+4);\
|
||||
T v21 = *(m_vec+5);\
|
||||
T v02 = *(m_vec+6);\
|
||||
T v12 = *(m_vec+7);\
|
||||
T v22 = *(m_vec+8);\
|
||||
T cof_00 = v11 * v22 - v21 * v12;\
|
||||
T cof_10 = v01 * v22 - v21 * v02;\
|
||||
T cof_20 = v01 * v12 - v11 * v02;\
|
||||
T det = (v00*cof_00-v10*cof_10+v20*cof_20);\
|
||||
if(is_zero(det,a_prec,a_fabs)) return false;\
|
||||
T cof_01 = v10 * v22 - v20 * v12;\
|
||||
T cof_11 = v00 * v22 - v20 * v02;\
|
||||
T cof_21 = v00 * v12 - v10 * v02;\
|
||||
T cof_02 = v10 * v21 - v20 * v11;\
|
||||
T cof_12 = v00 * v21 - v20 * v01;\
|
||||
T cof_22 = v00 * v11 - v10 * v01;\
|
||||
a_res.set_value(0,0,cof_00/det);\
|
||||
a_res.set_value(1,0,minus_one()*cof_01/det);\
|
||||
a_res.set_value(2,0,cof_02/det);\
|
||||
a_res.set_value(0,1,minus_one()*cof_10/det);\
|
||||
a_res.set_value(1,1,cof_11/det);\
|
||||
a_res.set_value(2,1,minus_one()*cof_12/det);\
|
||||
a_res.set_value(0,2,cof_20/det);\
|
||||
a_res.set_value(1,2,minus_one()*cof_21/det);\
|
||||
a_res.set_value(2,2,cof_22/det);\
|
||||
return true;\
|
||||
}\
|
||||
\
|
||||
/*Generic invertion method.*/\
|
||||
\
|
||||
unsigned int rord = ord-1;\
|
||||
unsigned int* cs = new unsigned int[rord];\
|
||||
unsigned int* rs = new unsigned int[rord];\
|
||||
\
|
||||
/* Get det with r = 0;*/\
|
||||
T det = zero();\
|
||||
T subdet;\
|
||||
{\
|
||||
{for(unsigned int i=0;i<rord;i++) {rs[i] = i+1;}}\
|
||||
{for(unsigned int i=0;i<rord;i++) {a_tmp_rs[i] = i+1;}}\
|
||||
unsigned int r = 0;\
|
||||
/*if(r>=1) rs[r-1] = r-1;*/\
|
||||
/*if(r>=1) a_tmp_rs[r-1] = r-1;*/\
|
||||
\
|
||||
{for(unsigned int i=0;i<rord;i++) {cs[i] = i+1;}}\
|
||||
{for(unsigned int i=0;i<rord;i++) {a_tmp_cs[i] = i+1;}}\
|
||||
bool sg = true; /*r=0+c=0*/\
|
||||
for(unsigned int c=0;c<ord;c++) {\
|
||||
if(c>=1) cs[c-1] = c-1;\
|
||||
T subdet = sub_determinant(rord,rs,cs);\
|
||||
T sgn = sg ? one() : minus_one();\
|
||||
det += value(r,c) * subdet * sgn;\
|
||||
T _value = subdet * sgn;\
|
||||
a_res.set_value(c,r,_value);\
|
||||
sg = sg?false:true;\
|
||||
if(c>=1) a_tmp_cs[c-1] = c-1;\
|
||||
subdet = sub_determinant_prec(rord,a_tmp_rs,a_tmp_cs,a_prec,a_fabs);\
|
||||
if(sg) {\
|
||||
det += value(r,c) * subdet;\
|
||||
a_res.set_value(c,r,subdet);\
|
||||
sg = false;\
|
||||
} else {\
|
||||
det += value(r,c) * subdet * minus_one();\
|
||||
a_res.set_value(c,r,subdet * minus_one());\
|
||||
sg = true;\
|
||||
}\
|
||||
}}\
|
||||
\
|
||||
if(det==zero()) {\
|
||||
delete [] cs;\
|
||||
delete [] rs;\
|
||||
return false;\
|
||||
} \
|
||||
\
|
||||
if(is_zero(det,a_prec,a_fabs)) return false;\
|
||||
\
|
||||
{for(unsigned int c=0;c<ord;c++) {\
|
||||
a_res.set_value(c,0,a_res.value(c,0)/det);\
|
||||
}}\
|
||||
\
|
||||
{for(unsigned int i=0;i<rord;i++) {rs[i] = i+1;}}\
|
||||
{for(unsigned int i=0;i<rord;i++) {a_tmp_rs[i] = i+1;}}\
|
||||
bool sgr = false; /*r=1+c=0*/\
|
||||
for(unsigned int r=1;r<ord;r++) {\
|
||||
if(r>=1) rs[r-1] = r-1;\
|
||||
{for(unsigned int i=0;i<rord;i++) {cs[i] = i+1;}}\
|
||||
if(r>=1) a_tmp_rs[r-1] = r-1;\
|
||||
{for(unsigned int i=0;i<rord;i++) {a_tmp_cs[i] = i+1;}}\
|
||||
bool sg = sgr;\
|
||||
for(unsigned int c=0;c<ord;c++) {\
|
||||
if(c>=1) cs[c-1] = c-1;\
|
||||
T subdet = sub_determinant(rord,rs,cs);\
|
||||
T sgn = sg ? one() : minus_one();\
|
||||
T _value = (subdet * sgn)/det;\
|
||||
a_res.set_value(c,r,_value);\
|
||||
sg = sg?false:true;\
|
||||
if(c>=1) a_tmp_cs[c-1] = c-1;\
|
||||
subdet = sub_determinant_prec(rord,a_tmp_rs,a_tmp_cs,a_prec,a_fabs);\
|
||||
if(sg) {\
|
||||
a_res.set_value(c,r,subdet/det);\
|
||||
sg = false;\
|
||||
} else {\
|
||||
a_res.set_value(c,r,(subdet * minus_one())/det);\
|
||||
sg = true;\
|
||||
}\
|
||||
}\
|
||||
sgr = sgr?false:true;\
|
||||
}\
|
||||
\
|
||||
delete [] cs;\
|
||||
delete [] rs;\
|
||||
\
|
||||
return true;\
|
||||
}\
|
||||
\
|
||||
template <class PREC>\
|
||||
bool invert_prec(TOOLS_MAT_CLASS& a_res,const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
|
||||
unsigned int ord = dimension();\
|
||||
if(ord==0) return true;\
|
||||
\
|
||||
if(ord==1) {\
|
||||
T det = value(0,0);\
|
||||
if(is_zero(det,a_prec,a_fabs)) return false;\
|
||||
a_res.set_value(0,0,one()/det);\
|
||||
return true;\
|
||||
} else if(ord==2) {\
|
||||
T v00 = *m_vec;\
|
||||
T v10 = *(m_vec+1);\
|
||||
T v01 = *(m_vec+2);\
|
||||
T v11 = *(m_vec+3);\
|
||||
T det = (v00 * v11 - v10 * v01);\
|
||||
if(is_zero(det,a_prec,a_fabs)) return false;\
|
||||
a_res.set_value(0,0,v11/det);\
|
||||
a_res.set_value(1,1,v00/det);\
|
||||
a_res.set_value(0,1,minus_one()*v01/det);\
|
||||
a_res.set_value(1,0,minus_one()*v10/det);\
|
||||
return true;\
|
||||
} else if(ord==3) {\
|
||||
/* 00 01 02 \
|
||||
10 11 12 \
|
||||
20 21 22 \
|
||||
*/\
|
||||
T v00 = *m_vec;\
|
||||
T v10 = *(m_vec+1);\
|
||||
T v20 = *(m_vec+2);\
|
||||
T v01 = *(m_vec+3);\
|
||||
T v11 = *(m_vec+4);\
|
||||
T v21 = *(m_vec+5);\
|
||||
T v02 = *(m_vec+6);\
|
||||
T v12 = *(m_vec+7);\
|
||||
T v22 = *(m_vec+8);\
|
||||
T cof_00 = v11 * v22 - v21 * v12;\
|
||||
T cof_10 = v01 * v22 - v21 * v02;\
|
||||
T cof_20 = v01 * v12 - v11 * v02;\
|
||||
T det = (v00*cof_00-v10*cof_10+v20*cof_20);\
|
||||
if(is_zero(det,a_prec,a_fabs)) return false;\
|
||||
T cof_01 = v10 * v22 - v20 * v12;\
|
||||
T cof_11 = v00 * v22 - v20 * v02;\
|
||||
T cof_21 = v00 * v12 - v10 * v02;\
|
||||
T cof_02 = v10 * v21 - v20 * v11;\
|
||||
T cof_12 = v00 * v21 - v20 * v01;\
|
||||
T cof_22 = v00 * v11 - v10 * v01;\
|
||||
a_res.set_value(0,0,cof_00/det);\
|
||||
a_res.set_value(1,0,minus_one()*cof_01/det);\
|
||||
a_res.set_value(2,0,cof_02/det);\
|
||||
a_res.set_value(0,1,minus_one()*cof_10/det);\
|
||||
a_res.set_value(1,1,cof_11/det);\
|
||||
a_res.set_value(2,1,minus_one()*cof_12/det);\
|
||||
a_res.set_value(0,2,cof_20/det);\
|
||||
a_res.set_value(1,2,minus_one()*cof_21/det);\
|
||||
a_res.set_value(2,2,cof_22/det);\
|
||||
return true;\
|
||||
}\
|
||||
\
|
||||
unsigned int rord = ord-1;\
|
||||
unsigned int* cs = new unsigned int[rord];\
|
||||
unsigned int* rs = new unsigned int[rord];\
|
||||
bool status = invert_prec(a_res,rs,cs,a_prec,a_fabs);\
|
||||
delete [] cs;\
|
||||
delete [] rs;\
|
||||
return status;\
|
||||
}\
|
||||
\
|
||||
bool invert(TOOLS_MAT_CLASS& a_res,unsigned int a_tmp_rs[],unsigned int a_tmp_cs[]) const { /*[rord=dim-1]*/ \
|
||||
return invert_prec<double>(a_res,a_tmp_rs,a_tmp_cs,0,zero_fabs);\
|
||||
}\
|
||||
\
|
||||
bool invert(TOOLS_MAT_CLASS& a_res) const {\
|
||||
return invert_prec<double>(a_res,0,zero_fabs);\
|
||||
}\
|
||||
\
|
||||
void power(unsigned int a_n,TOOLS_MAT_CLASS& a_res) const {\
|
||||
a_res.set_identity();\
|
||||
@@ -553,6 +743,36 @@ public:\
|
||||
a_res += tmp;\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
void cosh(unsigned int a_le,TOOLS_MAT_CLASS& a_res) const {\
|
||||
/* result = I + M**2/2! + M**4/4! + .... */\
|
||||
a_res.set_identity();\
|
||||
TOOLS_MAT_CLASS M_2(*this);\
|
||||
M_2._mul_mtx(m_vec);\
|
||||
TOOLS_MAT_CLASS tmp(*this);\
|
||||
tmp.set_identity();\
|
||||
for(unsigned int i=1;i<=a_le;i+=2) {\
|
||||
tmp *= M_2;\
|
||||
tmp.multiply(one()/T(i+0)); \
|
||||
tmp.multiply(one()/T(i+1)); \
|
||||
a_res += tmp;\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
void sinh(unsigned int a_le,TOOLS_MAT_CLASS& a_res) const {\
|
||||
/* result = M + M**3/3! + .... */\
|
||||
a_res._copy(m_vec);\
|
||||
TOOLS_MAT_CLASS M_2(*this);\
|
||||
M_2._mul_mtx(m_vec);\
|
||||
TOOLS_MAT_CLASS tmp(*this);\
|
||||
tmp._copy(m_vec);\
|
||||
for(unsigned int i=1;i<=a_le;i+=2) {\
|
||||
tmp *= M_2;\
|
||||
tmp.multiply(one()/T(i+1)); \
|
||||
tmp.multiply(one()/T(i+2)); \
|
||||
a_res += tmp;\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
void log(unsigned int a_le,TOOLS_MAT_CLASS& a_res) const {\
|
||||
/* result = (M-I) - (M-I)**2/2 + (M-I)**3/3 +... */\
|
||||
@@ -565,7 +785,7 @@ public:\
|
||||
M_I._add_mtx(m_vec);\
|
||||
\
|
||||
TOOLS_MAT_CLASS M_Ip(M_I);\
|
||||
T fact = -1;\
|
||||
T fact = minus_one();\
|
||||
\
|
||||
TOOLS_MAT_CLASS tmp;\
|
||||
\
|
||||
@@ -633,22 +853,22 @@ public: /*operators*/\
|
||||
}\
|
||||
protected:\
|
||||
void _copy(const T a_m[]) {\
|
||||
{T* tp = (T*)m_vec;T* ap = (T*)a_m;\
|
||||
for(unsigned int i=0;i<dim2();i++,tp++,ap++) *tp = *ap;}\
|
||||
T* tp = (T*)m_vec;T* ap = (T*)a_m;\
|
||||
for(unsigned int i=0;i<dim2();i++,tp++,ap++) *tp = *ap;\
|
||||
/*{for(unsigned int i=0;i<dim2();i++) m_vec[i] = a_m[i];}*/\
|
||||
/* memcpy does not work with std::complex<> and mat<symbol,4> see inlib/tests/symbolic.cpp */\
|
||||
/*vec_copy(m_vec,a_m,dim2());*/\
|
||||
}\
|
||||
\
|
||||
void _add_mtx(const T a_m[]) { /* this = this + a_m, */\
|
||||
{T* tp = (T*)m_vec;T* ap = (T*)a_m;\
|
||||
for(unsigned int i=0;i<dim2();i++,tp++,ap++) *tp += *ap;}\
|
||||
T* tp = (T*)m_vec;T* ap = (T*)a_m;\
|
||||
for(unsigned int i=0;i<dim2();i++,tp++,ap++) *tp += *ap;\
|
||||
/*for(unsigned int i=0;i<dim2();i++) m_vec[i] += a_m[i];*/\
|
||||
/*vec_add(m_vec,a_m,m_vec,dim2());*/\
|
||||
}\
|
||||
void _sub_mtx(const T a_m[]) { /* this = this - a_m, */\
|
||||
{T* tp = (T*)m_vec;T* ap = (T*)a_m;\
|
||||
for(unsigned int i=0;i<dim2();i++,tp++,ap++) *tp -= *ap;}\
|
||||
T* tp = (T*)m_vec;T* ap = (T*)a_m;\
|
||||
for(unsigned int i=0;i<dim2();i++,tp++,ap++) *tp -= *ap;\
|
||||
/*for(unsigned int i=0;i<dim2();i++) m_vec[i] -= a_m[i];*/\
|
||||
/*vec_sub(m_vec,a_m,m_vec,dim2());*/\
|
||||
}\
|
||||
@@ -716,7 +936,9 @@ protected:\
|
||||
delete [] res;\
|
||||
}\
|
||||
\
|
||||
T sub_determinant(unsigned int a_ord,unsigned int aRs[],unsigned int aCs[]) const {\
|
||||
template <class PREC>\
|
||||
T sub_determinant_prec(unsigned int a_ord,unsigned int aRs[],unsigned int aCs[],\
|
||||
const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
|
||||
/*WARNING : to optimize, we do not check the content of aRs, aCs.*/\
|
||||
unsigned int ord = a_ord;\
|
||||
if(ord==0) return zero();\
|
||||
@@ -725,17 +947,32 @@ protected:\
|
||||
/*return (value(aRs[0],aCs[0]) * value(aRs[1],aCs[1]) -\
|
||||
value(aRs[1],aCs[0]) * value(aRs[0],aCs[1])); \
|
||||
Optimize the upper :*/\
|
||||
\
|
||||
unsigned int r_0 = aRs[0];\
|
||||
unsigned int r_1 = aRs[1];\
|
||||
unsigned int c_0 = aCs[0];\
|
||||
unsigned int c_1 = aCs[1];\
|
||||
\
|
||||
unsigned int _ord = dimension();\
|
||||
const T* p = m_vec;\
|
||||
\
|
||||
return ( (*(p+r_0+c_0*_ord)) * (*(p+r_1+c_1*_ord)) -\
|
||||
(*(p+r_1+c_0*_ord)) * (*(p+r_0+c_1*_ord)) );\
|
||||
return ( (*(m_vec+aRs[0]+aCs[0]*_ord)) * (*(m_vec+aRs[1]+aCs[1]*_ord)) -\
|
||||
(*(m_vec+aRs[1]+aCs[0]*_ord)) * (*(m_vec+aRs[0]+aCs[1]*_ord)) );\
|
||||
\
|
||||
} else if(ord==3) {\
|
||||
/* 00 01 02 \
|
||||
10 11 12 \
|
||||
20 21 22 \
|
||||
*/\
|
||||
unsigned int _ord = dimension();\
|
||||
\
|
||||
T v00 = *(m_vec+aRs[0]+aCs[0]*_ord);\
|
||||
T v10 = *(m_vec+aRs[1]+aCs[0]*_ord);\
|
||||
T v20 = *(m_vec+aRs[2]+aCs[0]*_ord);\
|
||||
T v01 = *(m_vec+aRs[0]+aCs[1]*_ord);\
|
||||
T v11 = *(m_vec+aRs[1]+aCs[1]*_ord);\
|
||||
T v21 = *(m_vec+aRs[2]+aCs[1]*_ord);\
|
||||
T v02 = *(m_vec+aRs[0]+aCs[2]*_ord);\
|
||||
T v12 = *(m_vec+aRs[1]+aCs[2]*_ord);\
|
||||
T v22 = *(m_vec+aRs[2]+aCs[2]*_ord);\
|
||||
T cof_00 = v11 * v22 - v21 * v12;\
|
||||
T cof_10 = v01 * v22 - v21 * v02;\
|
||||
T cof_20 = v01 * v12 - v11 * v02;\
|
||||
return (v00*cof_00-v10*cof_10+v20*cof_20);\
|
||||
}\
|
||||
\
|
||||
unsigned int rord = ord-1;\
|
||||
@@ -754,8 +991,8 @@ protected:\
|
||||
for(unsigned int r=0;r<ord;r++) {\
|
||||
if(r>=1) rs[r-1] = aRs[r-1];\
|
||||
v_rc = value(aRs[r],aCs[c]);\
|
||||
if(v_rc!=zero()) {\
|
||||
T subdet = sub_determinant(rord,rs,cs);\
|
||||
if(!is_zero(v_rc,a_prec,a_fabs)) {\
|
||||
T subdet = sub_determinant_prec(rord,rs,cs,a_prec,a_fabs);\
|
||||
if(sg)\
|
||||
det += v_rc * subdet;\
|
||||
else\
|
||||
@@ -768,6 +1005,8 @@ protected:\
|
||||
delete [] rs;\
|
||||
\
|
||||
return det;\
|
||||
}
|
||||
}\
|
||||
\
|
||||
static double zero_fabs(const T& a_number) {return a_number==zero()?0:1000000;}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -97,12 +97,12 @@ public:
|
||||
if(is_empty()) {
|
||||
set_bounds(a_point,a_point);
|
||||
} else {
|
||||
m_min.set_value(tools::mn<T_t>(a_point[0],m_min[0]),
|
||||
tools::mn<T_t>(a_point[1],m_min[1]),
|
||||
tools::mn<T_t>(a_point[2],m_min[2]));
|
||||
m_max.set_value(tools::mx<T_t>(a_point[0],m_max[0]),
|
||||
tools::mx<T_t>(a_point[1],m_max[1]),
|
||||
tools::mx<T_t>(a_point[2],m_max[2]));
|
||||
m_min.set_value(min_of<T_t>(a_point[0],m_min[0]),
|
||||
min_of<T_t>(a_point[1],m_min[1]),
|
||||
min_of<T_t>(a_point[2],m_min[2]));
|
||||
m_max.set_value(max_of<T_t>(a_point[0],m_max[0]),
|
||||
max_of<T_t>(a_point[1],m_max[1]),
|
||||
max_of<T_t>(a_point[2],m_max[2]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,12 +112,12 @@ public:
|
||||
if(is_empty()) {
|
||||
set_bounds(a_x,a_y,a_z,a_x,a_y,a_z);
|
||||
} else {
|
||||
m_min.set_value(tools::mn<T_t>(a_x,m_min[0]),
|
||||
tools::mn<T_t>(a_y,m_min[1]),
|
||||
tools::mn<T_t>(a_z,m_min[2]));
|
||||
m_max.set_value(tools::mx<T_t>(a_x,m_max[0]),
|
||||
tools::mx<T_t>(a_y,m_max[1]),
|
||||
tools::mx<T_t>(a_z,m_max[2]));
|
||||
m_min.set_value(min_of<T_t>(a_x,m_min[0]),
|
||||
min_of<T_t>(a_y,m_min[1]),
|
||||
min_of<T_t>(a_z,m_min[2]));
|
||||
m_max.set_value(max_of<T_t>(a_x,m_max[0]),
|
||||
max_of<T_t>(a_y,m_max[1]),
|
||||
max_of<T_t>(a_z,m_max[2]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,12 +7,53 @@
|
||||
namespace tools {
|
||||
|
||||
template <class NUMBER,class PREC>
|
||||
inline bool numbers_are_equals(const NUMBER& a_left,const NUMBER& a_right,const PREC& a_prec,PREC(*a_fabs)(const NUMBER&)) {
|
||||
inline bool numbers_are_equal(const NUMBER& a_left,const NUMBER& a_right,const PREC& a_prec,PREC(*a_fabs)(const NUMBER&)) {
|
||||
NUMBER diff = a_left - a_right;
|
||||
if(a_fabs(diff)>=a_prec) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class NUMBER,class PREC>
|
||||
inline bool is_zero(const NUMBER& a_left,const PREC& a_prec,PREC(*a_fabs)(const NUMBER&)) {
|
||||
if(a_fabs(a_left)>=a_prec) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class NUMBER,class PREC>
|
||||
inline bool numbers_are_equal(const NUMBER& a_left,const NUMBER& a_right,const PREC& a_prec,PREC(*a_fabs)(NUMBER)) {
|
||||
NUMBER diff = a_left - a_right;
|
||||
if(a_fabs(diff)>=a_prec) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class VEC,class PREC>
|
||||
inline bool vectors_are_equal(const VEC& a_1,const VEC& a_2,const PREC& a_prec,PREC(*a_fabs)(PREC)) {
|
||||
if(a_1.size()!=a_2.size()) return false;
|
||||
typedef typename VEC::size_type sz_t;
|
||||
sz_t sz = a_1.size();
|
||||
//bool status = true;
|
||||
for(sz_t index=0;index<sz;index++) {
|
||||
if(!numbers_are_equal(a_1[index],a_2[index],a_prec,a_fabs))
|
||||
//{ ::printf("debug : vectors_are_equals : %lu : %g %g\n",index,a_1[index],a_2[index]);
|
||||
return false;
|
||||
//status = false;
|
||||
//}
|
||||
}
|
||||
return true;
|
||||
//return status;
|
||||
}
|
||||
|
||||
template <class VECVEC,class PREC>
|
||||
inline bool vecvecs_are_equal(const VECVEC& a_1,const VECVEC& a_2,const PREC& a_prec,PREC(*a_fabs)(PREC)) {
|
||||
if(a_1.size()!=a_2.size()) return false;
|
||||
typedef typename VECVEC::size_type sz_t;
|
||||
sz_t sz = a_1.size();
|
||||
for(sz_t index=0;index<sz;index++) {
|
||||
if(!vectors_are_equal(a_1[index],a_2[index],a_prec,a_fabs)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -89,6 +89,43 @@ inline bool inside(const std::pair<T,T>& a_P,const std::vector< std::pair<T,T> >
|
||||
return ((wn!=0)?true:false);
|
||||
}
|
||||
|
||||
template <class VEC2>
|
||||
inline bool intersect(const VEC2& P1,const VEC2& Q1,const VEC2& P2,const VEC2& Q2,VEC2& a_out) {
|
||||
// (P1,Q1) first line, (P2,Q2) second line and a_out intersection.
|
||||
// return false if no intersection. (For exa, parallel lines).
|
||||
|
||||
// P1+(Q1-P1)*r = P2+(Q2-P2)*s
|
||||
// (Q1-P1)*r - (Q2-P2)*s = P2-P1
|
||||
// r*(Q1-P1).v0 - s*(Q2-P2).v0 = (P2-P1).v0 //x
|
||||
// r*(Q1-P1).v1 - s*(Q2-P2).v1 = (P2-P1).v1 //y
|
||||
|
||||
// a*r + b*s = c
|
||||
// d*r + e*s = f
|
||||
|
||||
// r = (c*e-f*b)/(a*e-d*b)
|
||||
// s = (a*f-d*c)/(a*e-d*b)
|
||||
|
||||
typedef typename VEC2::elem_t T;
|
||||
VEC2 A = Q1-P1;
|
||||
VEC2 B = P2-Q2;
|
||||
VEC2 C = P2-P1;
|
||||
|
||||
T a = A.v0();
|
||||
T b = B.v0();
|
||||
T c = C.v0();
|
||||
T d = A.v1();
|
||||
T e = B.v1();
|
||||
T f = C.v1();
|
||||
|
||||
T det = a*e-d*b;
|
||||
if(det==T()) return false;
|
||||
|
||||
T r = (c*e-f*b)/det;
|
||||
|
||||
a_out = P1+A*r;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -116,9 +116,10 @@ protected:
|
||||
|
||||
namespace tools {
|
||||
|
||||
// not tested yet.
|
||||
template <class T>
|
||||
template <class VEC3>
|
||||
class clip {
|
||||
protected:
|
||||
typedef typename VEC3::elem_t T;
|
||||
public:
|
||||
clip():m_cur(0){}
|
||||
virtual ~clip() {}
|
||||
@@ -132,41 +133,41 @@ public:
|
||||
m_cur = 0;
|
||||
}
|
||||
|
||||
void add(const vec3<T>& a_point) {m_data[m_cur].push_back(a_point);}
|
||||
void add(const VEC3& a_point) {m_data[m_cur].push_back(a_point);}
|
||||
|
||||
void execute(const plane<T>& plane) {
|
||||
void execute(const plane<VEC3>& plane) {
|
||||
//Clip polygon against plane. This might change the number of
|
||||
//vertices in the polygon.
|
||||
|
||||
unsigned int n = m_data[m_cur].size();
|
||||
if (n == 0) return;
|
||||
size_t n = m_data[m_cur].size();
|
||||
if(!n) return;
|
||||
|
||||
// create a loop :
|
||||
vec3<T> dummy = m_data[m_cur][0];
|
||||
VEC3 dummy = m_data[m_cur][0];
|
||||
m_data[m_cur].push_back(dummy);
|
||||
|
||||
const vec3<T>& planeN = plane.normal();
|
||||
const VEC3& planeN = plane.normal();
|
||||
|
||||
for(unsigned int i = 0; i < n; i++) {
|
||||
vec3<T> v0 = m_data[m_cur][i];
|
||||
vec3<T> v1 = m_data[m_cur][i+1];
|
||||
for(size_t i = 0; i < n; i++) {
|
||||
VEC3 v0 = m_data[m_cur][i];
|
||||
VEC3 v1 = m_data[m_cur][i+1];
|
||||
|
||||
T d0 = plane.distance(v0);
|
||||
T d1 = plane.distance(v1);
|
||||
|
||||
if (d0 >= 0.0f && d1 < 0.0f) { // exit plane
|
||||
vec3<T> dir = v1-v0;
|
||||
VEC3 dir = v1-v0;
|
||||
// we know that v0 != v1 since we got here
|
||||
dir.normalize();
|
||||
T dot = dir.dot(planeN);
|
||||
vec3<T> newvertex = v0 - dir * (d0/dot);
|
||||
VEC3 newvertex = v0 - dir * (d0/dot);
|
||||
out_point(newvertex);
|
||||
} else if (d0 < 0.0f && d1 >= 0.0f) { // enter plane
|
||||
vec3<T> dir = v1-v0;
|
||||
VEC3 dir = v1-v0;
|
||||
// we know that v0 != v1 since we got here
|
||||
dir.normalize();
|
||||
T dot = dir.dot(planeN);
|
||||
vec3<T> newvertex = v0 - dir * (d0/dot);
|
||||
VEC3 newvertex = v0 - dir * (d0/dot);
|
||||
out_point(newvertex);
|
||||
out_point(v1);
|
||||
} else if (d0 >= 0.0f && d1 >= 0.0f) { // in plane
|
||||
@@ -177,13 +178,13 @@ public:
|
||||
m_cur ^= 1;
|
||||
}
|
||||
|
||||
const std::vector< vec3<T> >& result() const {return m_data[m_cur];}
|
||||
const std::vector<VEC3>& result() const {return m_data[m_cur];}
|
||||
|
||||
protected:
|
||||
void out_point(const vec3<T>& a_p) {m_data[m_cur ^ 1].push_back(a_p);}
|
||||
void out_point(const VEC3& a_p) {m_data[m_cur ^ 1].push_back(a_p);}
|
||||
|
||||
protected:
|
||||
std::vector< vec3<T> > m_data[2];
|
||||
std::vector<VEC3> m_data[2];
|
||||
unsigned int m_cur;
|
||||
};
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
const VEC3& direction() const {return m_dir;}
|
||||
|
||||
/* not tested :
|
||||
VEC3 closest_point(const VEC3& a_point) const {
|
||||
void closest_point(const VEC3& a_point,VEC& a_out) const {
|
||||
//from coin3d/SbLine.cpp.
|
||||
|
||||
//
|
||||
@@ -76,12 +76,11 @@ public:
|
||||
// \|
|
||||
// x a_point
|
||||
|
||||
return m_pos + m_dir * ((a_point - m_pos).dot(m_dir));
|
||||
a_out = m_pos + m_dir * ((a_point - m_pos).dot(m_dir));
|
||||
}
|
||||
|
||||
|
||||
bool closest_points(const line<T>& a_line,
|
||||
VEC3& a_on_this,VEC3& a_on_line) const {
|
||||
bool closest_points(const line<T>& a_line,VEC3& a_on_this,VEC3& a_on_line) const {
|
||||
//from coin3d/SbLine.cpp.
|
||||
|
||||
//WARNING : if ret false, a_on_this, a_on_line not set.
|
||||
@@ -100,10 +99,8 @@ public:
|
||||
T c[3], d[3];
|
||||
|
||||
for(unsigned int i=0;i<3;i++) {
|
||||
d[i] =
|
||||
D1[i] - D0N[i]*(D0[0]*D1[0] + D0[1]*D1[1] + D0[2]*D1[2]);
|
||||
c[i] =
|
||||
P1[i] - P0[i] + D0N[i]*(D0[0]*P0[0] + D0[1]*P0[1] + D0[2]*P0[2]);
|
||||
d[i] = D1[i] - D0N[i]*(D0[0]*D1[0] + D0[1]*D1[1] + D0[2]*D1[2]);
|
||||
c[i] = P1[i] - P0[i] + D0N[i]*(D0[0]*P0[0] + D0[1]*P0[1] + D0[2]*P0[2]);
|
||||
}
|
||||
|
||||
T den = d[0]*d[0]+d[1]*d[1]+d[2]*d[2];
|
||||
@@ -112,7 +109,7 @@ public:
|
||||
T t = -(c[0]*d[0]+c[1]*d[1]+c[2]*d[2]) / den;
|
||||
|
||||
a_on_line = a_line.m_pos + a_line.m_dir * t;
|
||||
a_on_this = closest_point(a_on_line);
|
||||
closest_point(a_on_line,a_on_this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,11 +30,13 @@ private:
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
mat(bool a_inc = true) {
|
||||
mat(
|
||||
#ifdef TOOLS_MEM
|
||||
bool a_inc = true
|
||||
#endif
|
||||
) {
|
||||
#ifdef TOOLS_MEM
|
||||
if(a_inc) mem::increment(s_class().c_str());
|
||||
#else
|
||||
(void)a_inc;
|
||||
#endif
|
||||
#ifdef TOOLS_MAT_NEW
|
||||
m_vec = new T[D*D];
|
||||
@@ -161,6 +163,25 @@ inline nmat<T> copy(const mat<T,D>& a_from) {
|
||||
return v;
|
||||
}
|
||||
|
||||
template <class VECTOR>
|
||||
inline void multiply(VECTOR& a_vec,const typename VECTOR::value_type& a_mat) {
|
||||
//typedef typename VECTOR::size_type sz_t;
|
||||
//sz_t number = a_vec.size();
|
||||
//for(sz_t index=0;index<number;index++) a_vec[index] *= a_mat;
|
||||
typedef typename VECTOR::iterator it_t;
|
||||
for(it_t it=a_vec.begin();it!=a_vec.end();++it) *it *= a_mat;
|
||||
}
|
||||
|
||||
template <class VECTOR>
|
||||
inline void multiply(VECTOR& a_vec,const typename VECTOR::value_type::elem_t& a_value) {
|
||||
typedef typename VECTOR::iterator it_t;
|
||||
for(it_t it=a_vec.begin();it!=a_vec.end();++it) (*it).multiply(a_value);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
/// related to complex numbers : //////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class MAT>
|
||||
inline void conjugate(MAT& a_m,typename MAT::elem_t (*a_conj)(const typename MAT::elem_t&)) {
|
||||
typedef typename MAT::elem_t T;
|
||||
@@ -171,12 +192,104 @@ inline void conjugate(MAT& a_m,typename MAT::elem_t (*a_conj)(const typename MAT
|
||||
}
|
||||
}
|
||||
|
||||
template <class MAT>
|
||||
inline bool is_real(MAT& a_m,typename MAT::elem_t::value_type (*a_imag)(const typename MAT::elem_t&)) {
|
||||
typedef typename MAT::elem_t T;
|
||||
T* pos = const_cast<T*>(a_m.data());
|
||||
unsigned int D2 = a_m.dimension()*a_m.dimension();
|
||||
for(unsigned int i=0;i<D2;i++,pos++) {if(a_imag(*pos)) return false;}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class MAT,class PREC>
|
||||
inline bool is_real_prec(MAT& a_m,typename MAT::elem_t::value_type (*a_imag)(const typename MAT::elem_t&),
|
||||
const PREC& a_prec,PREC(*a_fabs)(const typename MAT::elem_t::value_type&)) {\
|
||||
typedef typename MAT::elem_t T;
|
||||
T* pos = const_cast<T*>(a_m.data());
|
||||
unsigned int D2 = a_m.dimension()*a_m.dimension();
|
||||
for(unsigned int i=0;i<D2;i++,pos++) {if(a_fabs(a_imag(*pos))>=a_prec) return false;}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class MAT>
|
||||
inline bool is_imag(MAT& a_m,typename MAT::elem_t::value_type (*a_real)(const typename MAT::elem_t&)) {
|
||||
typedef typename MAT::elem_t T;
|
||||
T* pos = const_cast<T*>(a_m.data());
|
||||
unsigned int D2 = a_m.dimension()*a_m.dimension();
|
||||
for(unsigned int i=0;i<D2;i++,pos++) {if(a_real(*pos)) return false;}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class CMAT,class RMAT>
|
||||
inline bool to_real(const CMAT& a_c,RMAT& a_r,typename CMAT::elem_t::value_type (*a_real)(const typename CMAT::elem_t&)) {
|
||||
if(a_r.dimension()!=a_c.dimension()) return false;
|
||||
typedef typename CMAT::elem_t CT;
|
||||
const CT* cpos = a_c.data();
|
||||
typedef typename RMAT::elem_t RT;
|
||||
RT* rpos = const_cast<RT*>(a_r.data());
|
||||
unsigned int D2 = a_c.dimension()*a_c.dimension();
|
||||
for(unsigned int i=0;i<D2;i++,cpos++,rpos++) *rpos = a_real(*cpos);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class MAT>
|
||||
inline void dagger(MAT& a_m,typename MAT::elem_t (*a_conj)(const typename MAT::elem_t&)) {
|
||||
conjugate<MAT>(a_m,a_conj);
|
||||
a_m.transpose();
|
||||
}
|
||||
|
||||
template <class CMAT,class RMAT>
|
||||
inline bool decomplex(const CMAT& a_c,RMAT& a_r,
|
||||
typename CMAT::elem_t::value_type (*a_real)(const typename CMAT::elem_t&),
|
||||
typename CMAT::elem_t::value_type (*a_imag)(const typename CMAT::elem_t&)) {
|
||||
// CMAT = X+iY
|
||||
// RMAT = | X Y |
|
||||
// | -Y X |
|
||||
typedef typename CMAT::elem_t CT; //std::complex<double>
|
||||
typedef typename RMAT::elem_t RT; //double
|
||||
|
||||
unsigned int cdim = a_c.dimension();
|
||||
if(a_r.dimension()!=2*cdim) {a_r.set_zero();return false;}
|
||||
RT value;unsigned int r,c;
|
||||
for(r=0;r<cdim;r++) {
|
||||
for(c=0;c<cdim;c++) {
|
||||
const CT& cvalue = a_c.value(r,c);
|
||||
value = a_real(cvalue);
|
||||
a_r.set_value(r,c,value);
|
||||
a_r.set_value(r+cdim,c+cdim,value);
|
||||
value = a_imag(cvalue);
|
||||
a_r.set_value(r,c+cdim,value);
|
||||
a_r.set_value(r+cdim,c,-value);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class VEC_CMAT,class VEC_RMAT>
|
||||
inline bool decomplex(
|
||||
const VEC_CMAT& a_vc,VEC_RMAT& a_vr
|
||||
,typename VEC_CMAT::value_type::elem_t::value_type (*a_real)(const typename VEC_CMAT::value_type::elem_t&)
|
||||
,typename VEC_CMAT::value_type::elem_t::value_type (*a_imag)(const typename VEC_CMAT::value_type::elem_t&)
|
||||
) {
|
||||
// CMAT = X+iY
|
||||
// RMAT = | X Y |
|
||||
// | -Y X |
|
||||
typedef typename VEC_CMAT::size_type sz_t;
|
||||
sz_t number = a_vc.size();
|
||||
a_vr.resize(number);
|
||||
for(sz_t index=0;index<number;index++) {
|
||||
if(!decomplex(a_vc[index],a_vr[index],a_real,a_imag)) {
|
||||
a_vr.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//for sf, mf :
|
||||
//template <class T,unsigned int D>
|
||||
//inline const T* get_data(const mat<T,D>& a_v) {return a_v.data();}
|
||||
@@ -409,7 +522,7 @@ inline void matrix_set(MAT& a_m
|
||||
,const typename MAT::elem_t& a_40,const typename MAT::elem_t& a_41,const typename MAT::elem_t& a_42,const typename MAT::elem_t& a_43,const typename MAT::elem_t& a_44 //5 row
|
||||
){
|
||||
//a_<R><C>
|
||||
//vec[R + C * 4];
|
||||
//vec[R + C * 5];
|
||||
typename MAT::elem_t* vec = const_cast<typename MAT::elem_t*>(a_m.data());
|
||||
vec[0] = a_00;vec[5] = a_01;vec[10] = a_02;vec[15] = a_03;vec[20] = a_04;
|
||||
vec[1] = a_10;vec[6] = a_11;vec[11] = a_12;vec[16] = a_13;vec[21] = a_14;
|
||||
@@ -418,6 +531,29 @@ inline void matrix_set(MAT& a_m
|
||||
vec[4] = a_40;vec[9] = a_41;vec[14] = a_42;vec[19] = a_43;vec[24] = a_44;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
/// specific D=6 ///////////////////////////////
|
||||
////////////////////////////////////////////////
|
||||
template <class MAT>
|
||||
inline void matrix_set(MAT& a_m
|
||||
,const typename MAT::elem_t& a_00,const typename MAT::elem_t& a_01,const typename MAT::elem_t& a_02,const typename MAT::elem_t& a_03,const typename MAT::elem_t& a_04,const typename MAT::elem_t& a_05 //1 row
|
||||
,const typename MAT::elem_t& a_10,const typename MAT::elem_t& a_11,const typename MAT::elem_t& a_12,const typename MAT::elem_t& a_13,const typename MAT::elem_t& a_14,const typename MAT::elem_t& a_15 //2 row
|
||||
,const typename MAT::elem_t& a_20,const typename MAT::elem_t& a_21,const typename MAT::elem_t& a_22,const typename MAT::elem_t& a_23,const typename MAT::elem_t& a_24,const typename MAT::elem_t& a_25 //3 row
|
||||
,const typename MAT::elem_t& a_30,const typename MAT::elem_t& a_31,const typename MAT::elem_t& a_32,const typename MAT::elem_t& a_33,const typename MAT::elem_t& a_34,const typename MAT::elem_t& a_35 //4 row
|
||||
,const typename MAT::elem_t& a_40,const typename MAT::elem_t& a_41,const typename MAT::elem_t& a_42,const typename MAT::elem_t& a_43,const typename MAT::elem_t& a_44,const typename MAT::elem_t& a_45 //5 row
|
||||
,const typename MAT::elem_t& a_50,const typename MAT::elem_t& a_51,const typename MAT::elem_t& a_52,const typename MAT::elem_t& a_53,const typename MAT::elem_t& a_54,const typename MAT::elem_t& a_55 //6 row
|
||||
){
|
||||
//a_<R><C>
|
||||
//vec[R + C * 6];
|
||||
typename MAT::elem_t* vec = const_cast<typename MAT::elem_t*>(a_m.data());
|
||||
vec[0] = a_00;vec[ 6] = a_01;vec[12] = a_02;vec[18] = a_03;vec[24] = a_04;vec[30] = a_05;
|
||||
vec[1] = a_10;vec[ 7] = a_11;vec[13] = a_12;vec[19] = a_13;vec[25] = a_14;vec[31] = a_15;
|
||||
vec[2] = a_20;vec[ 8] = a_21;vec[14] = a_22;vec[20] = a_23;vec[26] = a_24;vec[32] = a_25;
|
||||
vec[3] = a_30;vec[ 9] = a_31;vec[15] = a_32;vec[21] = a_33;vec[27] = a_34;vec[33] = a_35;
|
||||
vec[4] = a_40;vec[10] = a_41;vec[16] = a_42;vec[22] = a_43;vec[28] = a_44;vec[34] = a_45;
|
||||
vec[5] = a_50;vec[11] = a_51;vec[17] = a_52;vec[23] = a_53;vec[29] = a_54;vec[35] = a_55;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
@@ -15,7 +15,11 @@ class mat4 : public mat<T,4> {
|
||||
typedef mat<T,4> parent;
|
||||
typedef mat<T,4> pr;
|
||||
public:
|
||||
#ifdef TOOLS_MEM
|
||||
mat4(bool a_inc = true):parent(a_inc) {}
|
||||
#else
|
||||
mat4():parent() {}
|
||||
#endif
|
||||
mat4(const mat<T,4>& a_from):parent(a_from){}
|
||||
virtual ~mat4() {}
|
||||
public:
|
||||
@@ -465,11 +469,11 @@ private:static void check_instantiation() {mat4<float> dummy;}
|
||||
/// common matrices : //////////////////////////
|
||||
////////////////////////////////////////////////
|
||||
|
||||
template <class T>
|
||||
inline const mat4<T>& mat4_zero() {
|
||||
static const mat4<T> s_v(false); //inc mem count = false
|
||||
return s_v;
|
||||
}
|
||||
#ifdef TOOLS_MEM
|
||||
template <class T> inline const mat4<T>& mat4_zero() {static const mat4<T> s_v(false);return s_v;}
|
||||
#else
|
||||
template <class T> inline const mat4<T>& mat4_zero() {static const mat4<T> s_v;return s_v;}
|
||||
#endif
|
||||
|
||||
/*
|
||||
template <class T>
|
||||
|
||||
@@ -183,6 +183,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
template <class MAT4>
|
||||
void set_value(const MAT4& a_m,T(*a_sqrt)(T)) {
|
||||
//WARNING : not tested.
|
||||
@@ -220,6 +221,7 @@ public:
|
||||
m_quat.multiply(one()/a_sqrt(a_m.v33()));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
template <class MAT4>
|
||||
void value(MAT4& a_m) const {
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
bool value(vec3f& a_from,float a_a) const {
|
||||
return parent::value(a_from,a_a,::sinf,::acosf); //WARNING acos and not cos
|
||||
}
|
||||
void set_value(const mat4f& a_m) {parent::set_value(a_m,::sqrtf);}
|
||||
//void set_value(const mat4f& a_m) {parent::set_value(a_m,::sqrtf);}
|
||||
void value(mat4f& a_m) const {parent::value(a_m);}
|
||||
|
||||
//NOTE : don't handle a static object because of mem balance.
|
||||
|
||||
@@ -40,11 +40,13 @@ public:
|
||||
m_data[1] = a_vec[1];
|
||||
m_data[2] = a_vec[2];
|
||||
}
|
||||
vec3(const T& a0,const T& a1,const T& a2,bool a_inc = true) {
|
||||
vec3(const T& a0,const T& a1,const T& a2
|
||||
#ifdef TOOLS_MEM
|
||||
,bool a_inc = true
|
||||
#endif
|
||||
) {
|
||||
#ifdef TOOLS_MEM
|
||||
if(a_inc) mem::increment(s_class().c_str());
|
||||
#else
|
||||
(void)a_inc;
|
||||
#endif
|
||||
m_data[0] = a0;
|
||||
m_data[1] = a1;
|
||||
@@ -295,18 +297,15 @@ public: //for iv2sg
|
||||
}
|
||||
|
||||
public:
|
||||
static const vec3<T>& s_x() {
|
||||
static const vec3<T> s_v(1,0,0,false);
|
||||
return s_v;
|
||||
}
|
||||
static const vec3<T>& s_y() {
|
||||
static const vec3<T> s_v(0,1,0,false);
|
||||
return s_v;
|
||||
}
|
||||
static const vec3<T>& s_z() {
|
||||
static const vec3<T> s_v(0,0,1,false);
|
||||
return s_v;
|
||||
}
|
||||
#if defined(TOOLS_MEM) && !defined(TOOLS_MEM_ATEXIT)
|
||||
static const vec3<T>& s_x() {static const vec3<T> s_v(1,0,0,false);return s_v;}
|
||||
static const vec3<T>& s_y() {static const vec3<T> s_v(0,1,0,false);return s_v;}
|
||||
static const vec3<T>& s_z() {static const vec3<T> s_v(0,0,1,false);return s_v;}
|
||||
#else
|
||||
static const vec3<T>& s_x() {static const vec3<T> s_v(1,0,0);return s_v;}
|
||||
static const vec3<T>& s_y() {static const vec3<T> s_v(0,1,0);return s_v;}
|
||||
static const vec3<T>& s_z() {static const vec3<T> s_v(0,0,1);return s_v;}
|
||||
#endif
|
||||
protected:
|
||||
T m_data[3];
|
||||
|
||||
@@ -318,8 +317,8 @@ template <class T>
|
||||
inline const T* get_data(const vec3<T>& a_v) {return a_v.data();}
|
||||
|
||||
template <class T>
|
||||
inline void normal(const vec3<T>& a_p0,const vec3<T>& a_p1,const vec3<T>& a_p2,vec3<T>& a_nm,
|
||||
vec3<T>& a_tmp_1,vec3<T>& a_tmp_2,T(*a_sqrt)(T)) {
|
||||
inline void get_normal(const vec3<T>& a_p0,const vec3<T>& a_p1,const vec3<T>& a_p2,vec3<T>& a_nm,
|
||||
vec3<T>& a_tmp_1,vec3<T>& a_tmp_2,T(*a_sqrt)(T)) {
|
||||
// Used to optimize sg::bin().
|
||||
//(a_p1-a_p0).cross(a_p2-a_p1,a_nm);
|
||||
|
||||
@@ -336,9 +335,9 @@ inline void normal(const vec3<T>& a_p0,const vec3<T>& a_p1,const vec3<T>& a_p2,v
|
||||
|
||||
/*
|
||||
template <class VEC3>
|
||||
inline void normal(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2,VEC3& a_nm) {
|
||||
inline void get_normal(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2,VEC3& a_nm) {
|
||||
VEC3 tmp1,tmp2;
|
||||
normal(a_p0,a_p1,a_p2,a_nm,tmp1,tmp2);
|
||||
get_normal(a_p0,a_p1,a_p2,a_nm,tmp1,tmp2);
|
||||
}
|
||||
*/
|
||||
template <class VEC3>
|
||||
|
||||
@@ -110,8 +110,8 @@ inline vec3f operator*(float a_f,const vec3f& a_v) {
|
||||
|
||||
#define TOOLS_VEC3F_MORE_PREC
|
||||
#ifdef TOOLS_VEC3F_MORE_PREC
|
||||
inline void normal(const vec3f& a_p0,const vec3f& a_p1,const vec3f& a_p2,vec3f& a_nm,
|
||||
vec3f& a_tmp_1,vec3f& a_tmp_2) {
|
||||
inline void get_normal(const vec3f& a_p0,const vec3f& a_p1,const vec3f& a_p2,vec3f& a_nm,
|
||||
vec3f& a_tmp_1,vec3f& a_tmp_2) {
|
||||
// Used to optimize sg::bin().
|
||||
//(a_p1-a_p0).cross(a_p2-a_p1,a_nm);
|
||||
|
||||
@@ -126,9 +126,9 @@ inline void normal(const vec3f& a_p0,const vec3f& a_p1,const vec3f& a_p2,vec3f&
|
||||
a_nm.normalize();
|
||||
}
|
||||
#else
|
||||
inline void normal(const vec3f& a_p0,const vec3f& a_p1,const vec3f& a_p2,vec3f& a_nm,
|
||||
vec3f& a_tmp_1,vec3f& a_tmp_2) {
|
||||
normal<float>(a_p0,a_p1,a_p2,a_nm,a_tmp_1,a_tmp_2,::sqrtf);
|
||||
inline void get_normal(const vec3f& a_p0,const vec3f& a_p1,const vec3f& a_p2,vec3f& a_nm,
|
||||
vec3f& a_tmp_1,vec3f& a_tmp_2) {
|
||||
get_normal<float>(a_p0,a_p1,a_p2,a_nm,a_tmp_1,a_tmp_2,::sqrtf);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -46,11 +46,13 @@ public:
|
||||
m_data[2] = a_vec[2];
|
||||
m_data[3] = a_vec[3];
|
||||
}
|
||||
vec4(const T& a0,const T& a1,const T& a2,const T& a3,bool a_inc = true) {
|
||||
vec4(const T& a0,const T& a1,const T& a2,const T& a3
|
||||
#ifdef TOOLS_MEM
|
||||
,bool a_inc = true
|
||||
#endif
|
||||
) {
|
||||
#ifdef TOOLS_MEM
|
||||
if(a_inc) mem::increment(s_class().c_str());
|
||||
#else
|
||||
(void)a_inc;
|
||||
#endif
|
||||
m_data[0] = a0;
|
||||
m_data[1] = a1;
|
||||
|
||||
@@ -17,8 +17,11 @@ public:
|
||||
public:
|
||||
vec4f():parent() {}
|
||||
vec4f(const float a_vec[4]):parent(a_vec) {}
|
||||
vec4f(const float& a0,const float& a1,const float& a2,const float& a3,bool a_inc = true)
|
||||
:parent(a0,a1,a2,a3,a_inc){}
|
||||
#ifdef TOOLS_MEM
|
||||
vec4f(const float& a0,const float& a1,const float& a2,const float& a3,bool a_inc = true):parent(a0,a1,a2,a3,a_inc){}
|
||||
#else
|
||||
vec4f(const float& a0,const float& a1,const float& a2,const float& a3):parent(a0,a1,a2,a3){}
|
||||
#endif
|
||||
virtual ~vec4f() {}
|
||||
public:
|
||||
vec4f(const vec4f& a_from):parent(a_from){}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_mapmanip
|
||||
#define tools_mapmanip
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace tools {
|
||||
|
||||
template <class K,class V>
|
||||
inline void safe_clear(std::map<K,V*>& a_m){
|
||||
// the below takes into account the case in
|
||||
// which "delete entry" could modify a_m.
|
||||
typedef typename std::map<K,V*>::iterator it_t;
|
||||
while(!a_m.empty()) {
|
||||
it_t it = a_m.begin();
|
||||
V* entry = (*it).second;
|
||||
a_m.erase(it);
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
|
||||
template <class K,class V>
|
||||
inline void find_and_remove_value(std::map<K,V*>& a_m,V* a_value){
|
||||
typedef typename std::map<K,V*>::iterator it_t;
|
||||
while(true) {
|
||||
bool found = false;
|
||||
for(it_t it=a_m.begin();it!=a_m.end();++it) {
|
||||
if((*it).second==a_value) {
|
||||
a_m.erase(it);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TOOLS_DEPRECATED
|
||||
template <class K,class V> inline void clear(std::map<K,V*>& a_m){safe_clear<K,V>(a_m);}
|
||||
#endif
|
||||
|
||||
template <class K,class V>
|
||||
inline void delete_key(std::map<K,V*>& a_m,const K& a_key){
|
||||
typedef typename std::map<K,V*>::iterator it_t;
|
||||
it_t it = a_m.find(a_key);
|
||||
if(it==a_m.end()) return;
|
||||
V* obj = (*it).second;
|
||||
a_m.erase(it);
|
||||
delete obj;
|
||||
}
|
||||
|
||||
template <class K,class V>
|
||||
inline void raw_clear(std::map<K,V*>& a_m){
|
||||
typedef typename std::map<K,V*>::iterator it_t;
|
||||
for(it_t it=a_m.begin();it!=a_m.end();++it) delete (*it).second;
|
||||
a_m.clear();
|
||||
}
|
||||
|
||||
template <class K,class V>
|
||||
inline void copy(std::map<K,V*>& a_to,const std::map<K,V*>& a_from){
|
||||
raw_clear<K,V>(a_to);
|
||||
typedef typename std::map<K,V*>::const_iterator it_t;
|
||||
for(it_t it=a_from.begin();it!=a_from.end();++it) {
|
||||
a_to[(*it).first] = (*it).second->copy();
|
||||
}
|
||||
}
|
||||
|
||||
template <class K,class V>
|
||||
inline bool find(const std::map<K,V>& a_map,const K& a_key,V& a_value) {
|
||||
typedef typename std::map<K,V>::const_iterator it_t;
|
||||
it_t it = a_map.find(a_key);
|
||||
if(it==a_map.end()) {a_value = V();return false;}
|
||||
a_value = (*it).second;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -18,14 +18,18 @@
|
||||
namespace tools {
|
||||
|
||||
class mem {
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::mem");
|
||||
return s_v;
|
||||
}
|
||||
protected:
|
||||
mem(){increment();}
|
||||
virtual ~mem(){decrement();}
|
||||
mem(){increment(s_class().c_str());}
|
||||
virtual ~mem(){decrement(s_class().c_str());}
|
||||
mem(const mem&){}
|
||||
mem& operator=(const mem&){return *this;}
|
||||
public:
|
||||
static void increment(){counter()++;}
|
||||
static void decrement(){counter()--;}
|
||||
//static void increment(){counter()++;}
|
||||
//static void decrement(){counter()--;}
|
||||
|
||||
static void increment(const char* a_class){
|
||||
counter()++;
|
||||
@@ -88,13 +92,13 @@ public:
|
||||
}
|
||||
list().clear();
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
static int& counter() {
|
||||
static int s_count = 0;
|
||||
return s_count;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
static bool& check_by_class() {
|
||||
static bool s_check_by_class = false;
|
||||
return s_check_by_class;
|
||||
@@ -103,8 +107,8 @@ protected:
|
||||
typedef std::list< std::pair<std::string,int> > mem_list;
|
||||
|
||||
static mem_list& list() {
|
||||
static mem_list s_list;
|
||||
return s_list;
|
||||
static mem_list* s_list = new mem_list(); //have it on the heap, so that an atexit logic works.
|
||||
return *s_list;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -7,14 +7,17 @@
|
||||
namespace tools {
|
||||
|
||||
template <class T>
|
||||
inline T mn(const T& a,const T& b) {
|
||||
return (a<b?a:b);
|
||||
}
|
||||
inline T mn(const T& a,const T& b) {return (a<b?a:b);}
|
||||
|
||||
template <class T>
|
||||
inline T mx(const T& a,const T& b) {
|
||||
return (a>b?a:b);
|
||||
}
|
||||
inline T mx(const T& a,const T& b) {return (a>b?a:b);}
|
||||
|
||||
// long name :
|
||||
template <class T>
|
||||
inline T min_of(const T& a,const T& b) {return (a<b?a:b);}
|
||||
|
||||
template <class T>
|
||||
inline T max_of(const T& a,const T& b) {return (a>b?a:b);}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,12 @@ typedef void* MPI_Comm;
|
||||
typedef void* MPI_Datatype;
|
||||
|
||||
#define MPI_UNSIGNED 0
|
||||
#define MPI_FLOAT 0
|
||||
#define MPI_DOUBLE 0
|
||||
#define MPI_UNSIGNED_CHAR 0
|
||||
#define MPI_CHAR 0
|
||||
#define MPI_LONG 0
|
||||
#define MPI_SHORT 0
|
||||
#define MPI_INT 0
|
||||
#define MPI_UNSIGNED_LONG 0
|
||||
#define MPI_LONG_LONG 0
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_mpi_pntuple
|
||||
#define tools_mpi_pntuple
|
||||
|
||||
// pntuple = for parallel ntupling.
|
||||
|
||||
#include <tools/wroot/base_pntuple>
|
||||
#include <tools/S_STRING>
|
||||
#include <tools/impi>
|
||||
|
||||
namespace tools {
|
||||
namespace mpi {
|
||||
|
||||
class pntuple : public tools::wroot::base_pntuple {
|
||||
typedef tools::wroot::base_pntuple parent;
|
||||
public:
|
||||
static tools::uint32 protocol_basket() {return 1;}
|
||||
static tools::uint32 protocol_end_fill() {return 2;}
|
||||
public:
|
||||
pntuple(std::ostream& a_out,
|
||||
bool a_byte_swap,tools::uint32 a_compression,
|
||||
const std::string& a_name,const std::string& a_title,bool a_verbose)
|
||||
:parent(a_out,a_byte_swap,a_compression,a_name,a_title,a_verbose)
|
||||
{}
|
||||
pntuple(std::ostream& a_out,bool a_byte_swap,tools::uint32 a_compression,tools::wroot::seek a_seek_directory,
|
||||
const std::vector<tools::uint32>& a_basket_sizes,const tools::ntuple_booking& a_bkg,bool a_verbose)
|
||||
:parent(a_out,a_byte_swap,a_compression,a_seek_directory,a_basket_sizes,a_bkg,a_verbose)
|
||||
{}
|
||||
virtual ~pntuple() {}
|
||||
protected:
|
||||
pntuple(const pntuple& a_from):parent(a_from){}
|
||||
pntuple& operator=(const pntuple& a_from){parent::operator=(a_from);return *this;}
|
||||
|
||||
protected:
|
||||
class basket_add : public virtual tools::wroot::branch::iadd_basket {
|
||||
typedef tools::wroot::branch::iadd_basket parent;
|
||||
public:
|
||||
virtual bool add_basket(tools::wroot::basket& a_basket) {
|
||||
m_mpi.pack_reset();
|
||||
if(!m_mpi.pack(protocol_basket())) return false;
|
||||
if(!m_mpi.pack(m_icol)) return false;
|
||||
|
||||
if(!m_mpi.spack(a_basket.object_name())) return false;
|
||||
if(!m_mpi.spack(a_basket.object_title())) return false;
|
||||
|
||||
if(!m_mpi.pack(a_basket.last())) return false;
|
||||
if(!m_mpi.pack(a_basket.nev_buf_size())) return false;
|
||||
if(!m_mpi.pack(a_basket.nev())) return false;
|
||||
|
||||
if(a_basket.entry_offset()) {
|
||||
if(!m_mpi.bpack(true)) return false;
|
||||
if(!m_mpi.pack(a_basket.nev_buf_size(),a_basket.entry_offset())) return false;
|
||||
} else {
|
||||
if(!m_mpi.bpack(false)) return false;
|
||||
}
|
||||
|
||||
if(a_basket.displacement()) {
|
||||
if(!m_mpi.bpack(true)) return false;
|
||||
if(!m_mpi.pack(a_basket.nev_buf_size(),a_basket.displacement())) return false;
|
||||
} else {
|
||||
if(!m_mpi.bpack(false)) return false;
|
||||
}
|
||||
|
||||
if(!m_mpi.pack(a_basket.datbuf().length(),a_basket.datbuf().buf())) return false;
|
||||
|
||||
if(!m_mpi.send_buffer(m_dest,m_tag)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
basket_add(file& a_file,tools::impi& a_mpi,int a_dest,int a_tag,tools::uint32 a_icol)
|
||||
:m_file(a_file),m_mpi(a_mpi),m_dest(a_dest),m_tag(a_tag),m_icol(a_icol)
|
||||
{}
|
||||
protected:
|
||||
basket_add(const basket_add& a_from):parent()
|
||||
,m_file(a_from.m_file),m_mpi(a_from.m_mpi),m_dest(a_from.m_dest),m_tag(a_from.m_tag),m_icol(a_from.m_icol)
|
||||
{}
|
||||
basket_add& operator=(const basket_add& a_from){
|
||||
m_file = a_from.m_file;
|
||||
m_dest = a_from.m_dest;
|
||||
m_tag = a_from.m_tag;
|
||||
m_icol = a_from.m_icol;
|
||||
return *this;
|
||||
}
|
||||
protected:
|
||||
file m_file;
|
||||
tools::impi& m_mpi;
|
||||
int m_dest;
|
||||
int m_tag;
|
||||
tools::uint32 m_icol;
|
||||
};
|
||||
|
||||
public:
|
||||
bool add_row(tools::impi& a_mpi,int a_dest,int a_tag) {
|
||||
if(m_cols.empty()) return false;
|
||||
|
||||
tools_vforit(tools::wroot::icol*,m_cols,it) (*it)->add();
|
||||
|
||||
tools::uint32 icol = 0;
|
||||
tools_vforit(tools::wroot::icol*,m_cols,it) {
|
||||
basket_add _badd(m_file,a_mpi,a_dest,a_tag,icol);icol++;
|
||||
if(!(*it)->get_branch()->pfill(_badd)) return false;
|
||||
}
|
||||
|
||||
tools_vforit(tools::wroot::icol*,m_cols,it) (*it)->set_def();
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
void end_leaves(std::vector<tools::uint32>& a_lengths,std::vector<int>& a_mxs) const {
|
||||
a_lengths.clear();
|
||||
a_mxs.clear();
|
||||
tools_vforcit(tools::wroot::icol*,m_cols,it) {
|
||||
tools::wroot::base_leaf* _leaf = (*it)->get_leaf();
|
||||
tools::wroot::leaf_string* _leafs = _leaf?tools::id_cast<tools::wroot::base_leaf,tools::wroot::leaf_string>(*_leaf):0;
|
||||
if(_leafs) {
|
||||
a_lengths.push_back(_leafs->length());
|
||||
a_mxs.push_back(_leafs->get_max());
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
bool end_fill(tools::impi& a_mpi,int a_dest,int a_tag) {
|
||||
tools::uint32 icol = 0;
|
||||
tools_vforit(tools::wroot::icol*,m_cols,it) {
|
||||
basket_add _badd(m_file,a_mpi,a_dest,a_tag,icol);icol++;
|
||||
if(!(*it)->get_branch()->end_pfill(_badd)) return false;
|
||||
}
|
||||
std::vector<tools::uint32> lengths;
|
||||
std::vector<int> mxs;
|
||||
end_leaves(lengths,mxs);
|
||||
|
||||
a_mpi.pack_reset();
|
||||
if(!a_mpi.pack(protocol_end_fill())) return false;
|
||||
if(!a_mpi.vpack(lengths)) return false;
|
||||
if(!a_mpi.vpack(mxs)) return false;
|
||||
if(!a_mpi.send_buffer(a_dest,a_tag)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
inline tools::wroot::basket* get_basket(std::ostream& a_out,tools::impi& a_mpi,
|
||||
bool a_byte_swap,tools::wroot::seek a_seek_directory,
|
||||
tools::uint32 a_basket_size) {
|
||||
std::string oname;
|
||||
if(!a_mpi.sunpack(oname)) return 0;
|
||||
std::string otitle;
|
||||
if(!a_mpi.sunpack(otitle)) return 0;
|
||||
|
||||
tools::uint32 last,nev_buf_size,nev;
|
||||
if(!a_mpi.unpack(last)) return 0;
|
||||
if(!a_mpi.unpack(nev_buf_size)) return 0;
|
||||
if(!a_mpi.unpack(nev)) return 0;
|
||||
|
||||
int* entry_offset = 0;
|
||||
{bool not_null;
|
||||
if(!a_mpi.bunpack(not_null)) return 0;
|
||||
if(not_null) {
|
||||
tools::uint32 n;
|
||||
if(!a_mpi.unpack(n,entry_offset)) return 0;
|
||||
}}
|
||||
|
||||
int* displacement = 0;
|
||||
{bool not_null;
|
||||
if(!a_mpi.bunpack(not_null)) return 0;
|
||||
if(not_null) {
|
||||
tools::uint32 n;
|
||||
if(!a_mpi.unpack(n,displacement)) return 0;
|
||||
}}
|
||||
|
||||
tools::uint32 _size;
|
||||
char* _buffer;
|
||||
if(!a_mpi.unpack(_size,_buffer)) {a_out << "unpack(buffer) failed."<< std::endl;return 0;}
|
||||
|
||||
// wbasket fields set at file writing :
|
||||
//m_buf_size,m_buffer,m_nbytes,m_object_size,m_date,m_cycle,m_seek_key
|
||||
|
||||
//::printf("debug : col = %d, %s, %s, %lu\n",
|
||||
// icol,rbasket.object_class().c_str(),rbasket.object_name().c_str(),rbasket.seek_key());
|
||||
|
||||
tools::wroot::basket* basket = new tools::wroot::basket(a_out,a_byte_swap,a_seek_directory,
|
||||
oname,otitle,"TBasket",a_basket_size,
|
||||
false/*verbose*/);
|
||||
basket->datbuf().write_fast_array(_buffer,_size);
|
||||
basket->set_nev(last,nev_buf_size,nev,entry_offset,displacement);
|
||||
|
||||
delete [] _buffer;
|
||||
|
||||
return basket;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -4,17 +4,12 @@
|
||||
#ifndef tools_mpi_wrmpi
|
||||
#define tools_mpi_wrmpi
|
||||
|
||||
#ifdef TOOLS_USE_NATIVE_MPI
|
||||
#include <mpi.h>
|
||||
#else
|
||||
#include "dummy_mpi.h"
|
||||
#endif
|
||||
#include "wait_buffer"
|
||||
|
||||
#include <tools/impi>
|
||||
#include <tools/vdata>
|
||||
#include <tools/realloc>
|
||||
#include <tools/mnmx>
|
||||
#include <ostream>
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
#include <tools/mem>
|
||||
@@ -53,6 +48,36 @@ protected:
|
||||
return s_v;
|
||||
}
|
||||
public: //inlib::mpi::impi
|
||||
virtual bool pack(char a_val) {
|
||||
tools::uint32 sz = tools::uint32(sizeof(char));
|
||||
if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
|
||||
if(::MPI_Pack(&a_val,1,MPI_CHAR,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
|
||||
m_out << "tools::mpi::wrmpi : MPI_Pack(char) failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
m_pos += sz;
|
||||
return true;
|
||||
}
|
||||
virtual bool pack(short a_val) {
|
||||
tools::uint32 sz = tools::uint32(sizeof(short));
|
||||
if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
|
||||
if(::MPI_Pack(&a_val,1,MPI_SHORT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
|
||||
m_out << "tools::mpi::wrmpi : MPI_Pack(short) failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
m_pos += sz;
|
||||
return true;
|
||||
}
|
||||
virtual bool pack(int a_val) {
|
||||
tools::uint32 sz = tools::uint32(sizeof(int));
|
||||
if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
|
||||
if(::MPI_Pack(&a_val,1,MPI_INT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
|
||||
m_out << "tools::mpi::wrmpi : MPI_Pack(int) failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
m_pos += sz;
|
||||
return true;
|
||||
}
|
||||
virtual bool pack(unsigned int a_val) {
|
||||
tools::uint32 sz = tools::uint32(sizeof(unsigned int));
|
||||
if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
|
||||
@@ -83,6 +108,16 @@ public: //inlib::mpi::impi
|
||||
m_pos += sz;
|
||||
return true;
|
||||
}
|
||||
virtual bool pack(float a_val) {
|
||||
tools::uint32 sz = tools::uint32(sizeof(float));
|
||||
if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
|
||||
if(::MPI_Pack(&a_val,1,MPI_FLOAT,m_buffer,m_size,&m_ipos,m_comm)!=MPI_SUCCESS) {
|
||||
m_out << "tools::mpi::wrmpi : MPI_Pack(float) failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
m_pos += sz;
|
||||
return true;
|
||||
}
|
||||
virtual bool pack(double a_val) {
|
||||
tools::uint32 sz = tools::uint32(sizeof(double));
|
||||
if(m_pos+sz>m_max) {if(!expand2(m_size+sz)) return false;}
|
||||
@@ -197,6 +232,30 @@ public: //inlib::mpi::impi
|
||||
return true;
|
||||
}
|
||||
public: //inlib::mpi::impi
|
||||
virtual bool unpack(char& a_val) {
|
||||
if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_CHAR,m_comm)!=MPI_SUCCESS) {
|
||||
m_out << "tools::mpi::wrmpi : MPI_Unpack(char) failed." << std::endl;
|
||||
a_val = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool unpack(short& a_val) {
|
||||
if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_SHORT,m_comm)!=MPI_SUCCESS) {
|
||||
m_out << "tools::mpi::wrmpi : MPI_Unpack(short) failed." << std::endl;
|
||||
a_val = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool unpack(int& a_val) {
|
||||
if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_INT,m_comm)!=MPI_SUCCESS) {
|
||||
m_out << "tools::mpi::wrmpi : MPI_Unpack(int) failed." << std::endl;
|
||||
a_val = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool unpack(unsigned int& a_val) {
|
||||
if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_UNSIGNED,m_comm)!=MPI_SUCCESS) {
|
||||
m_out << "tools::mpi::wrmpi : MPI_Unpack(unsigned int) failed." << std::endl;
|
||||
@@ -221,6 +280,14 @@ public: //inlib::mpi::impi
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool unpack(float& a_val) {
|
||||
if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_FLOAT,m_comm)!=MPI_SUCCESS) {
|
||||
m_out << "tools::mpi::wrmpi : MPI_Unpack(float) failed." << std::endl;
|
||||
a_val = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual bool unpack(double& a_val) {
|
||||
if(::MPI_Unpack(m_buffer,m_size,&m_ipos,&a_val,1,MPI_DOUBLE,m_comm)!=MPI_SUCCESS) {
|
||||
m_out << "tools::mpi::wrmpi : MPI_Unpack(double) failed." << std::endl;
|
||||
@@ -330,6 +397,28 @@ public: //inlib::mpi::impi
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool wait_buffer(int a_rank,int a_src,int a_tag,int& a_probe_src,bool a_verbose = false) {
|
||||
int buffer_size = 0;
|
||||
char* _buffer = 0;
|
||||
if (!mpi::wait_buffer(m_out,a_rank,a_src,a_tag,m_comm,buffer_size,_buffer,a_probe_src,a_verbose)) {
|
||||
m_out << "tools::mpi::wrmpi::wait_buffer : failed for rank " << a_rank << " and source " << a_src <<"." << std::endl;
|
||||
return false;
|
||||
}
|
||||
// we take ownership of buffer :
|
||||
delete [] m_buffer;
|
||||
m_size = buffer_size;
|
||||
m_buffer = _buffer;
|
||||
m_max = m_buffer+m_size;
|
||||
m_pos = m_buffer;
|
||||
m_ipos = 0; //IMPORTANT
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool wait_buffer(int a_rank,int a_tag,int& a_probe_src,bool a_verbose = false) {
|
||||
return wait_buffer(a_rank,MPI_ANY_SOURCE,a_tag,a_probe_src,a_verbose);
|
||||
}
|
||||
|
||||
public:
|
||||
wrmpi(std::ostream& a_out,const MPI_Comm& a_comm,tools::uint32 a_size = 128) // we expect a_size!=0
|
||||
:m_out(a_out)
|
||||
|
||||
@@ -10,32 +10,38 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "forit"
|
||||
#include "cids"
|
||||
|
||||
namespace tools {
|
||||
|
||||
class column_binding {
|
||||
public:
|
||||
column_binding(const std::string& a_name,void* a_user_obj)
|
||||
column_binding(const std::string& a_name,cid a_cid,void* a_user_obj)
|
||||
:m_name(a_name)
|
||||
,m_cid(a_cid)
|
||||
,m_user_obj(a_user_obj) //WARNING : not owner.
|
||||
{}
|
||||
virtual ~column_binding() {}
|
||||
public:
|
||||
column_binding(const column_binding& a_from)
|
||||
:m_name(a_from.m_name)
|
||||
,m_cid(a_from.m_cid)
|
||||
,m_user_obj(a_from.m_user_obj)
|
||||
{}
|
||||
column_binding& operator=(const column_binding& a_from) {
|
||||
if(&a_from==this) return *this;
|
||||
m_name = a_from.m_name;
|
||||
m_cid = a_from.m_cid;
|
||||
m_user_obj = a_from.m_user_obj;
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
const std::string& name() const {return m_name;}
|
||||
cid get_cid() const {return m_cid;}
|
||||
void* user_obj() const {return m_user_obj;}
|
||||
protected:
|
||||
std::string m_name;
|
||||
cid m_cid;
|
||||
void* m_user_obj;
|
||||
};
|
||||
|
||||
@@ -55,15 +61,60 @@ public:
|
||||
public:
|
||||
template <class T>
|
||||
void add_column(const std::string& a_name,T& a_user_var) {
|
||||
m_columns.push_back(column_binding(a_name,(void*)&a_user_var));
|
||||
m_columns.push_back(column_binding(a_name,_cid(T()),(void*)&a_user_var));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void add_column(const std::string& a_name,std::vector<T>& a_user_var) {
|
||||
m_columns.push_back(column_binding(a_name,_cid_std_vector<T>(),(void*)&a_user_var));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void add_column_cid(const std::string& a_name,T& a_user_var) {
|
||||
m_columns.push_back(column_binding(a_name,T::id_class(),(void*)&a_user_var));
|
||||
}
|
||||
|
||||
void add_column_no_var(const std::string& a_name) { //used in rcsv_ntuple.
|
||||
m_columns.push_back(column_binding(a_name,0,0));
|
||||
}
|
||||
|
||||
//void add_column(const std::string& a_name,cid a_id,void* a_user_var) {
|
||||
// m_columns.push_back(column_binding(a_name,a_id,a_user_var));
|
||||
//}
|
||||
|
||||
const std::vector<column_binding>& columns() const {return m_columns;}
|
||||
|
||||
bool find_user_obj(const std::string& a_name,cid& a_cid,void*& a_obj) const {
|
||||
tools_vforcit(column_binding,m_columns,it) {
|
||||
if((*it).name()==a_name) {
|
||||
a_cid = (*it).get_cid();
|
||||
a_obj = (*it).user_obj();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
a_cid = 0;
|
||||
a_obj = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T* find_variable(const std::string& a_name) const {
|
||||
tools_vforcit(column_binding,m_columns,it) {
|
||||
if((*it).name()==a_name) return (T*)((*it).user_obj());
|
||||
if((*it).name()==a_name) {
|
||||
// we should check cid. If so, take care of T=aida::ntuple.
|
||||
return (T*)((*it).user_obj());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::vector<T>* find_vector_variable(const std::string& a_name) const {
|
||||
tools_vforcit(column_binding,m_columns,it) {
|
||||
if((*it).name()==a_name) {
|
||||
if((*it).get_cid()!=_cid_std_vector<T>()) return 0;
|
||||
return (std::vector<T>*)((*it).user_obj());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include "cids"
|
||||
|
||||
#include <ostream>
|
||||
#include "forit"
|
||||
|
||||
namespace tools {
|
||||
|
||||
class column_booking {
|
||||
@@ -68,6 +71,15 @@ public:
|
||||
m_columns.push_back(column_booking(a_name,_cid(T()),0));
|
||||
}
|
||||
template <class T>
|
||||
void add_column_vec(const std::string& a_name) {
|
||||
m_columns.push_back(column_booking(a_name,_cid_std_vector<T>(),0));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void add_column(const std::string& a_name,T& a_user) {
|
||||
m_columns.push_back(column_booking(a_name,_cid(T()),(void*)&a_user));
|
||||
}
|
||||
template <class T>
|
||||
void add_column(const std::string& a_name,std::vector<T>& a_user_vec) {
|
||||
m_columns.push_back(column_booking(a_name,_cid_std_vector<T>(),(void*)&a_user_vec));
|
||||
}
|
||||
@@ -79,6 +91,37 @@ public:
|
||||
|
||||
void set_name(const std::string& a_s) {m_name = a_s;}
|
||||
void set_title(const std::string& a_s) {m_title = a_s;}
|
||||
|
||||
bool has_similar_layout(std::ostream& a_out,const ntuple_booking& a_nbk) {
|
||||
if(m_columns.size()!=a_nbk.m_columns.size()) {
|
||||
a_out << "tools::ntuple_booking::has_similar_layout :"
|
||||
<< " bookings have not the same number of columns."
|
||||
<< " (" << m_columns.size() << " != " << a_nbk.m_columns.size() << ")."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
std::vector<column_booking>::const_iterator ait = a_nbk.m_columns.begin();
|
||||
tools_vforit(tools::column_booking,m_columns,it) {
|
||||
if((*it).name()!=(*ait).name()) {
|
||||
a_out << "tools::ntuple_booking::has_similar_layout :"
|
||||
<< " columns don't have same name."
|
||||
<< " (" << (*it).name() << " != " << (*ait).name() << ")."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
if((*it).cls_id()!=(*ait).cls_id()) {
|
||||
a_out << "tools::ntuple_booking::has_similar_layout :"
|
||||
<< " columns don't have same class id."
|
||||
<< " (" << (*it).cls_id() << " != " << (*ait).cls_id() << ")."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
ait++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string m_name;
|
||||
std::string m_title;
|
||||
|
||||
@@ -182,23 +182,24 @@ inline char* compiler() {
|
||||
toss(compiler_name(),pos,l);pos += l;
|
||||
|
||||
#if defined(__clang__)
|
||||
*pos++ = '_';
|
||||
*pos = '_';pos++;
|
||||
tosu<unsigned int>(__clang_major__,pos,l);pos += l;
|
||||
tosu<unsigned int>(__clang_minor__,pos,l);pos += l;
|
||||
tosu<unsigned int>(__clang_patchlevel__,pos,l);pos += l;
|
||||
#elif defined(__GNUC__)
|
||||
*pos++ = '_';
|
||||
*pos = '_';pos++;
|
||||
tosu<unsigned int>(__GNUC__,pos,l);pos += l;
|
||||
tosu<unsigned int>(__GNUC_MINOR__,pos,l);pos += l;
|
||||
tosu<unsigned int>(__GNUC_PATCHLEVEL__,pos,l);pos += l;
|
||||
#elif defined(_MSC_VER)
|
||||
*pos++ = '_';
|
||||
*pos = '_';pos++;
|
||||
tosu<unsigned int>(_MSC_VER,pos,l);pos += l;
|
||||
//_mfc_
|
||||
//tosu<unsigned int>(_MFC_VER,pos,l);pos += l;
|
||||
#elif defined(__alpha)
|
||||
#else
|
||||
#endif
|
||||
*pos = 0;
|
||||
return s_s;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,18 @@ inline bool to_pointer(const std::string& a_string,void*& a_value){
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool to_pointer(const char* a_string,void*& a_value){
|
||||
upointer v = 0;
|
||||
if(::sscanf(a_string,upointer_format_x(),&v)!=1) {
|
||||
if(::sscanf(a_string,upointer_format(),&v)!=1) {
|
||||
a_value = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
a_value = (void*)v;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool p2s(const void* a_value,std::string& a_s){
|
||||
char s[512];
|
||||
snpf(s,sizeof(s),upointer_format(),(upointer)a_value);
|
||||
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
while(read_header_line(m_reader,file_sz,line)) {
|
||||
// a_out << "line : " << sout(s) << std::endl;
|
||||
std::vector<std::string> _words;
|
||||
tools::words(line," ",false,_words);
|
||||
words(line," ",false,_words);
|
||||
if(!_words.size()) {
|
||||
a_out << "tools::rcsv::histo::read : syntax error : empty header line." << std::endl;
|
||||
return false;
|
||||
@@ -259,7 +259,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
if(a_verbose) a_out << "labels " << sout(line) << std::endl;
|
||||
tools::words(line,",",false,labels);}
|
||||
words(line,",",false,labels);}
|
||||
|
||||
unsigned int valn = 3+2*hdata.m_dimension;
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
#endif
|
||||
}
|
||||
virtual ~ntuple() {
|
||||
tools::clear<read::icol>(m_cols);
|
||||
safe_clear<read::icol>(m_cols);
|
||||
#ifdef TOOLS_MEM
|
||||
mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
@@ -187,7 +187,7 @@ public:
|
||||
|
||||
std::istream& istrm() {return m_reader;}
|
||||
|
||||
/* use tools::file::is_hippo for that.
|
||||
/* use file::is_hippo for that.
|
||||
static bool is_hippo(std::ostream& a_out,std::istream& a_reader) {
|
||||
// analyse two first data line.
|
||||
|
||||
@@ -209,7 +209,7 @@ public:
|
||||
if(s.find('\t')==std::string::npos) return false;
|
||||
|
||||
//std::vector<std::string> labels;
|
||||
//tools::words(s,"\t",false,labels);
|
||||
//words(s,"\t",false,labels);
|
||||
//return labels.size()?true:false;
|
||||
|
||||
return true;
|
||||
@@ -294,14 +294,12 @@ public:
|
||||
char a_sep = 0, //guessed
|
||||
const std::string& a_suffix = "x", //col suffix
|
||||
bool a_verbose = false) {
|
||||
tools::clear<read::icol>(m_cols);
|
||||
safe_clear<read::icol>(m_cols);
|
||||
m_sep = 0;
|
||||
m_sz = 0;
|
||||
|
||||
if(a_suffix.empty()) {
|
||||
a_out << "tools::rcsv::ntuple::initialize :"
|
||||
<< " expect a column suffix."
|
||||
<< std::endl;
|
||||
a_out << "tools::rcsv::ntuple::initialize : expect a column suffix." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -320,14 +318,26 @@ public:
|
||||
std::vector<std::string> labels;
|
||||
if(m_hippo) { //skip first two lines :
|
||||
std::string title;
|
||||
if(!read_line(m_reader,m_sz,title)) {m_sz = 0;return false;}
|
||||
if(!read_line(m_reader,m_sz,title)) {
|
||||
a_out << "tools::rcsv::ntuple::initialize : read_line() failed." << std::endl;
|
||||
m_sz = 0;
|
||||
return false;
|
||||
}
|
||||
std::string s;
|
||||
if(!read_line(m_reader,m_sz,s)) {m_sz = 0;return false;}
|
||||
tools::words(s,"\t",false,labels); //false for glast.tnt that has a trailing \t.
|
||||
if(!read_line(m_reader,m_sz,s)) {
|
||||
a_out << "tools::rcsv::ntuple::initialize : (2) read_line() failed." << std::endl;
|
||||
m_sz = 0;
|
||||
return false;
|
||||
}
|
||||
words(s,"\t",false,labels); //false for glast.tnt that has a trailing \t.
|
||||
} else {
|
||||
while(skip_comment(m_reader,m_sz)){}
|
||||
}
|
||||
if(m_reader.tellg()>=m_sz) {m_sz=0;return false;}
|
||||
if(m_reader.tellg()>=m_sz) {
|
||||
a_out << "tools::rcsv::ntuple::initialize : tellg() >= sz." << std::endl;
|
||||
m_sz=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// get first data line :
|
||||
std::string sfirst;
|
||||
@@ -376,18 +386,18 @@ public:
|
||||
|
||||
// in case sep is ' ', there is an ambiguity with some leading
|
||||
// space in front of first number.
|
||||
if(m_sep==' ') tools::strip(sfirst,leading,' ');
|
||||
if(m_sep==' ') strip(sfirst,leading,' ');
|
||||
|
||||
std::vector<std::string> words;
|
||||
std::vector<std::string> ws;
|
||||
{std::string sep;
|
||||
sep += m_sep;
|
||||
tools::words(sfirst,sep,m_hippo?false:true,words);}
|
||||
words(sfirst,sep,m_hippo?false:true,ws);}
|
||||
|
||||
// look if words are numbers :
|
||||
if(a_verbose) a_out << "words " << words.size() << std::endl;
|
||||
if(a_verbose) a_out << "words " << ws.size() << std::endl;
|
||||
unsigned int index = 0;
|
||||
std::vector<std::string>::iterator it;
|
||||
for(it=words.begin();it!=words.end();++it,index++) {
|
||||
for(it=ws.begin();it!=ws.end();++it,index++) {
|
||||
if(a_verbose) a_out << "word " << sout(*it) << "" << std::endl;
|
||||
/* with glast.tnt there is trailing \t that will induce an extra empty column.
|
||||
if((*it).empty()) {
|
||||
@@ -395,13 +405,13 @@ public:
|
||||
// <num><sep><num><sep><sep><num>...
|
||||
// but accept a trailing <sep> (glast.tnt) :
|
||||
// <num><sep><num>....<sep><num><sep>
|
||||
if(index==(words.size()-1)) {
|
||||
if(index==(ws.size()-1)) {
|
||||
break;
|
||||
} else {
|
||||
a_out << "tools::rcsv::ntuple::initialize :"
|
||||
<< " empty word."
|
||||
<< std::endl;
|
||||
tools::clear<read::icol>(m_cols);
|
||||
safe_clear<read::icol>(m_cols);
|
||||
m_sep = 0;
|
||||
m_sz = 0;
|
||||
return false;
|
||||
@@ -468,21 +478,22 @@ public:
|
||||
TOOLS_RCSV_NTUPLE_IF_CID(char,char)
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(short,short)
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(int,int)
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(int64,int64)
|
||||
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(float,float)
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(double,double)
|
||||
|
||||
else if(a_id==column<std::string>::id_class()) {
|
||||
static const std::string s_v("string");
|
||||
return s_v;
|
||||
}
|
||||
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(uchar,uchar)
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(ushort,ushort)
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(uint,uint32) //WARNING
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(bool,bool)
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(int64,int64)
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(uint64,uint64)
|
||||
|
||||
else TOOLS_RCSV_NTUPLE_IF_CID(bool,bool)
|
||||
else if(a_id==column<std::string>::id_class()) {
|
||||
static const std::string s_v("string");
|
||||
return s_v;
|
||||
}
|
||||
|
||||
else if(a_id==column<csv_time>::id_class()) {
|
||||
static const std::string s_v("time");
|
||||
return s_v;
|
||||
@@ -491,21 +502,22 @@ public:
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(char,char)
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(short,short)
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int,int)
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int64,int64)
|
||||
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(float,float)
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(double,double)
|
||||
|
||||
else if(a_id==column< std::vector<std::string> >::id_class()) {
|
||||
static const std::string s_v("string[]");
|
||||
return s_v;
|
||||
}
|
||||
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uchar,uchar)
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(ushort,ushort)
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uint,uint32) //WARNING
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(bool,bool)
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int64,int64)
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uint64,uint64)
|
||||
|
||||
else TOOLS_RCSV_NTUPLE_IF_VEC_CID(bool,bool)
|
||||
else if(a_id==column< std::vector<std::string> >::id_class()) {
|
||||
static const std::string s_v("string[]");
|
||||
return s_v;
|
||||
}
|
||||
|
||||
#undef TOOLS_RCSV_NTUPLE_IF_CID
|
||||
#undef TOOLS_RCSV_NTUPLE_IF_VEC_CID
|
||||
|
||||
@@ -535,7 +547,7 @@ public:
|
||||
bool initialize(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding()) {
|
||||
// it assumes a "commented header".
|
||||
|
||||
tools::clear<read::icol>(m_cols);
|
||||
safe_clear<read::icol>(m_cols);
|
||||
m_sep = 0;
|
||||
m_sz = 0;
|
||||
m_hippo = false;
|
||||
@@ -604,7 +616,7 @@ public:
|
||||
a_out << "tools::rcsv::ntuple::initialize(booking) :"
|
||||
<< " unhandled column type " << sout(type)
|
||||
<< std::endl;
|
||||
tools::clear<read::icol>(m_cols);
|
||||
safe_clear<read::icol>(m_cols);
|
||||
m_sep = 0;
|
||||
m_sz = 0;
|
||||
m_hippo = false;
|
||||
@@ -630,6 +642,16 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initialize_from_commented_header(std::ostream& a_out) { // it assumes a "commented header".
|
||||
std::string _title;
|
||||
char _sep,_vec_sep;
|
||||
std::vector<col_desc> _cols;
|
||||
if(!read_commented_header(a_out,m_reader,_title,_sep,_vec_sep,_cols)) return false;
|
||||
ntuple_binding nbd;
|
||||
{tools_vforcit(col_desc,_cols,it) nbd.add_column_no_var((*it).second);} //user_var is 0.
|
||||
return initialize(a_out,nbd);
|
||||
}
|
||||
|
||||
bool get_row() const {
|
||||
bool status = true;
|
||||
tools_vforcit(read::icol*,m_cols,it) {
|
||||
@@ -671,7 +693,7 @@ protected:
|
||||
if(!read_line(a_reader,sz,line)) break; //or return false ?
|
||||
|
||||
std::vector<std::string> _words;
|
||||
tools::words(line," ",false,_words);
|
||||
words(line," ",false,_words);
|
||||
if(!_words.size()) {
|
||||
a_out << "tools::rcsv::ntuple::read_commented_header :"
|
||||
<< " syntax error : empty header line."
|
||||
@@ -921,14 +943,14 @@ protected:
|
||||
for(it=m_cols.begin();it!=m_cols.end();++it,index++) {
|
||||
|
||||
#define TOOLS_RCSV_NTUPLE_IF_COL(a__type) \
|
||||
if(col_##a__type* _col_##a__type = tools::id_cast<icol_t,col_##a__type>(*(*it))) {\
|
||||
if(col_##a__type* _col_##a__type = id_cast<icol_t,col_##a__type>(*(*it))) {\
|
||||
a__type v;\
|
||||
if(!_read(m_reader,m_sz,m_sep,v)) return false;\
|
||||
_col_##a__type->set_value(v);\
|
||||
}
|
||||
|
||||
#define TOOLS_RCSV_NTUPLE_IF_VEC_COL(a__type) \
|
||||
if(col_vec_##a__type* _col_vec_##a__type = tools::id_cast<icol_t,col_vec_##a__type>(*(*it))) {\
|
||||
if(col_vec_##a__type* _col_vec_##a__type = id_cast<icol_t,col_vec_##a__type>(*(*it))) {\
|
||||
std::vector<a__type> v;\
|
||||
if(!_vec_read(m_reader,m_sz,iss,tmp,m_sep,vec_sep,v)) return false;\
|
||||
_col_vec_##a__type->set_value(v);\
|
||||
@@ -948,7 +970,7 @@ protected:
|
||||
else TOOLS_RCSV_NTUPLE_IF_COL(int64)
|
||||
else TOOLS_RCSV_NTUPLE_IF_COL(uint64)
|
||||
|
||||
else if(col_time* _col_time = tools::id_cast<icol_t,col_time>(*(*it))) {
|
||||
else if(col_time* _col_time = id_cast<icol_t,col_time>(*(*it))) {
|
||||
time_t v;
|
||||
if(!_read_time(m_reader,m_sz,m_sep,v)) return false;
|
||||
csv_time ct;ct.m_l = long(v);
|
||||
@@ -1039,9 +1061,9 @@ public:
|
||||
return m_freader.fail()?false:true;
|
||||
}
|
||||
bool initialize(std::ostream& a_out,
|
||||
char a_sep = 0, //guessed
|
||||
const std::string& a_suffix = "x", //col suffix
|
||||
bool a_verbose = false) {
|
||||
char a_sep = 0, //guessed
|
||||
const std::string& a_suffix = "x", //col suffix
|
||||
bool a_verbose = false) {
|
||||
if(!m_freader.is_open()) {
|
||||
m_freader.open(m_file.c_str());
|
||||
if(m_freader.fail()) {
|
||||
|
||||
@@ -37,8 +37,8 @@ public:
|
||||
}
|
||||
public: //icol
|
||||
virtual void* cast(cid a_class) const {
|
||||
if(void* p = cmp_cast<icolumn>(this,a_class)) {return p;}
|
||||
else return 0;
|
||||
if(void* p = cmp_cast<icolumn>(this,a_class)) return p;
|
||||
return 0;
|
||||
}
|
||||
virtual cid id_cls() const {return id_class();}
|
||||
public:
|
||||
|
||||
@@ -33,12 +33,14 @@ public:
|
||||
}
|
||||
public:
|
||||
virtual bool stream(buffer& a_buffer) {
|
||||
delete m_leaf_count;
|
||||
if(m_own_leaf_count) {
|
||||
if(a_buffer.map_objs()) a_buffer.remove_in_map(m_leaf_count);
|
||||
delete m_leaf_count;
|
||||
}
|
||||
m_leaf_count = 0;
|
||||
m_own_leaf_count = false;
|
||||
|
||||
int fLengthType;
|
||||
int fOffset;
|
||||
bool fIsRange;
|
||||
bool fIsUnsigned;
|
||||
|
||||
short v;
|
||||
@@ -52,14 +54,15 @@ public:
|
||||
|
||||
// Ok with v 1 & 2
|
||||
if(!a_buffer.read(m_length)) return false;
|
||||
if(!a_buffer.read(fLengthType)) return false;
|
||||
if(!a_buffer.read(m_length_type)) return false;
|
||||
if(!a_buffer.read(fOffset)) return false;
|
||||
if(!a_buffer.read(fIsRange)) return false;
|
||||
if(!a_buffer.read(m_is_range)) return false;
|
||||
if(!a_buffer.read(fIsUnsigned)) return false;
|
||||
|
||||
{ifac::args args;
|
||||
iro* obj;
|
||||
if(!a_buffer.read_object(m_fac,args,obj)) {
|
||||
bool created;
|
||||
if(!a_buffer.read_object(m_fac,args,obj,created)) {
|
||||
m_out << "tools::rroot::base_leaf::stream :"
|
||||
<< " can't read object."
|
||||
<< std::endl;
|
||||
@@ -76,9 +79,13 @@ public:
|
||||
<< " can't cast base_leaf."
|
||||
<< std::endl;
|
||||
m_leaf_count = 0;
|
||||
delete obj;
|
||||
if(created) {
|
||||
if(a_buffer.map_objs()) a_buffer.remove_in_map(obj);
|
||||
delete obj;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(created) m_own_leaf_count = true;
|
||||
}}
|
||||
|
||||
if(!a_buffer.check_byte_count(s,c,"TLeaf")) return false;
|
||||
@@ -103,22 +110,21 @@ public:
|
||||
|
||||
//,fIndirectAddress(false)
|
||||
//,fNewValue(false)
|
||||
,m_ndata(0)
|
||||
//,m_ndata(0)
|
||||
,m_length(0)
|
||||
/*
|
||||
,fLengthType(0)
|
||||
,fOffset(0)
|
||||
,fIsRange(false)
|
||||
,fIsUnsigned(false)
|
||||
*/
|
||||
,m_length_type(0)
|
||||
//,fOffset(0)
|
||||
,m_is_range(false)
|
||||
//,fIsUnsigned(false)
|
||||
,m_leaf_count(0)
|
||||
,m_own_leaf_count(false)
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
virtual ~base_leaf(){
|
||||
delete m_leaf_count;
|
||||
if(m_own_leaf_count) delete m_leaf_count;
|
||||
#ifdef TOOLS_MEM
|
||||
mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
@@ -128,14 +134,18 @@ protected:
|
||||
:iro(a_from)
|
||||
,m_out(a_from.m_out)
|
||||
,m_fac(a_from.m_fac)
|
||||
,m_ndata(0)
|
||||
//,m_ndata(0)
|
||||
,m_length(0)
|
||||
,m_length_type(0)
|
||||
,m_is_range(false)
|
||||
,m_leaf_count(0)
|
||||
,m_own_leaf_count(false)
|
||||
{}
|
||||
base_leaf& operator=(const base_leaf&){return *this;}
|
||||
public:
|
||||
const std::string& name() const {return m_name;}
|
||||
const std::string& title() const {return m_title;}
|
||||
const base_leaf* leaf_count() const {return m_leaf_count;}
|
||||
/*
|
||||
uint32 length() const {
|
||||
// Return the number of effective elements of this leaf.
|
||||
@@ -168,15 +178,14 @@ protected: //Named
|
||||
std::string m_title;
|
||||
//bool fIndirectAddress;
|
||||
//bool fNewValue;
|
||||
uint32 m_ndata; //! Number of elements in fAddress data buffer
|
||||
//uint32 m_ndata; //! Number of elements in fAddress data buffer
|
||||
uint32 m_length; // Number of fixed length elements
|
||||
/*
|
||||
int fLengthType; // Number of bytes for this data type
|
||||
int fOffset; // Offset in ClonesArray object (if one)
|
||||
bool fIsRange; // (=true if leaf has a range, false otherwise)
|
||||
bool fIsUnsigned; // (=kTRUE if unsigned, kFALSE otherwise)
|
||||
*/
|
||||
base_leaf* m_leaf_count; // Pointer to Leaf count if variable length
|
||||
uint32 m_length_type; // Number of bytes for this data type
|
||||
//int fOffset; // Offset in ClonesArray object (if one)
|
||||
bool m_is_range; // (=true if leaf has a range, false otherwise)
|
||||
//bool fIsUnsigned; // (=kTRUE if unsigned, kFALSE otherwise)
|
||||
base_leaf* m_leaf_count; // Pointer to Leaf count if variable length
|
||||
bool m_own_leaf_count;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "base_leaf"
|
||||
#include "basket"
|
||||
#include "named"
|
||||
#include "obj_array"
|
||||
#include "seek"
|
||||
#include "ifile"
|
||||
#include "ifac"
|
||||
@@ -460,14 +460,14 @@ public:
|
||||
{// There are (m_write_basket+1) sensitive elements in fBasketEntry :
|
||||
// (Do we have to check that ?)
|
||||
for(uint32 i=0;i<m_write_basket;i++) {
|
||||
uint32 first = fBasketEntry[i];
|
||||
uint32 last = fBasketEntry[i+1]-1;
|
||||
m_first_last.push_back(std::pair<uint32,uint32>(first,last));
|
||||
uint64 first = fBasketEntry[i];
|
||||
uint64 last = fBasketEntry[i+1]-1;
|
||||
m_first_last.push_back(std::pair<uint64,uint64>(first,last));
|
||||
}
|
||||
if(m_entry_number) {
|
||||
uint32 first = fBasketEntry[m_write_basket];
|
||||
uint32 last = m_entry_number-1;
|
||||
m_first_last.push_back(std::pair<uint32,uint32>(first,last));
|
||||
uint64 first = fBasketEntry[m_write_basket];
|
||||
uint64 last = m_entry_number-1;
|
||||
m_first_last.push_back(std::pair<uint64,uint64>(first,last));
|
||||
}}
|
||||
//_dump_first_last();
|
||||
|
||||
@@ -526,7 +526,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool find_entry(ifile& a_file,uint32 a_entry,uint32& a_nbytes){
|
||||
virtual bool find_entry(ifile& a_file,uint64 a_entry,uint32& a_nbytes){
|
||||
// Read all leaves of entry and return total number of bytes :
|
||||
// The input argument entry is the entry serial number in the current tree.
|
||||
a_nbytes = 0;
|
||||
@@ -555,8 +555,8 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 first = m_first_last[m_read_basket].first;
|
||||
uint32 last = m_first_last[m_read_basket].second;
|
||||
uint64 first = m_first_last[m_read_basket].first;
|
||||
uint64 last = m_first_last[m_read_basket].second;
|
||||
|
||||
// Are we still in the same ReadBasket?
|
||||
if((a_entry<first)||(a_entry>last)) {
|
||||
@@ -575,7 +575,7 @@ public:
|
||||
}
|
||||
if(!found) {
|
||||
uint32 count = 0;
|
||||
typedef std::pair<uint32,uint32> first_last;
|
||||
typedef std::pair<uint64,uint64> first_last;
|
||||
tools_vforcit(first_last,m_first_last,it) {
|
||||
first = (*it).first;
|
||||
last = (*it).second;
|
||||
@@ -662,7 +662,7 @@ public:
|
||||
uint32 bufbegin;
|
||||
{int* entry_offset = m__read_basket->entry_offset();
|
||||
if(entry_offset) {
|
||||
uint32 index = a_entry-first;
|
||||
uint32 index = uint32(a_entry-first);
|
||||
if(index>=m__read_basket->nev()) {
|
||||
m_out << "tools::rroot::branch::find_entry :"
|
||||
<< " can't access entry offset " << index
|
||||
@@ -673,7 +673,7 @@ public:
|
||||
bufbegin = entry_offset[index];
|
||||
//::printf("debug : xxx++ %u : %u\n",index,bufbegin);
|
||||
} else {
|
||||
bufbegin = m__read_basket->key_length() + (a_entry-first)*m__read_basket->nev_buf_size();
|
||||
bufbegin = (uint32)(m__read_basket->key_length() + (a_entry-first)*m__read_basket->nev_buf_size());
|
||||
}}
|
||||
|
||||
{int* displacement = m__read_basket->displacement();
|
||||
@@ -727,7 +727,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool show(std::ostream& a_out,ifile& a_file,uint32 a_entry) {
|
||||
virtual bool show(std::ostream& a_out,ifile& a_file,uint64 a_entry) {
|
||||
// Print values of all active leaves for entry :
|
||||
// if entry==-1, print current entry (default)
|
||||
uint32 n;
|
||||
@@ -760,7 +760,7 @@ public:
|
||||
:m_out(a_out)
|
||||
,m_fac(a_fac)
|
||||
|
||||
,m_streamed_baskets(m_fac,true)
|
||||
,m_streamed_baskets(m_fac,true,true)
|
||||
,m__read_basket(0)
|
||||
|
||||
//,m_bits(0)
|
||||
@@ -768,8 +768,8 @@ public:
|
||||
,m_title("")
|
||||
,fAutoDelete(false)
|
||||
|
||||
,m_branches(m_fac,true)
|
||||
,m_leaves(m_fac,true)
|
||||
,m_branches(m_fac,true,true)
|
||||
,m_leaves(m_fac,true,true)
|
||||
|
||||
,fEntryOffsetLen(0)
|
||||
,m_write_basket(0)
|
||||
@@ -793,9 +793,11 @@ protected:
|
||||
branch(const branch& a_from)
|
||||
:iro(a_from)
|
||||
,m_out(a_from.m_out),m_fac(a_from.m_fac)
|
||||
,m_streamed_baskets(m_fac,false),m__read_basket(0)
|
||||
,m_streamed_baskets(m_fac,false,true)
|
||||
,m__read_basket(0)
|
||||
,fAutoDelete(false)
|
||||
,m_branches(m_fac,false),m_leaves(m_fac,false)
|
||||
,m_branches(m_fac,false,true)
|
||||
,m_leaves(m_fac,false,true)
|
||||
,fEntryOffsetLen(1000)
|
||||
,m_write_basket(0)
|
||||
,m_entry_number(0)
|
||||
@@ -894,10 +896,10 @@ protected:
|
||||
m_out << "tools::rroot::branch::_dump_first_last :"
|
||||
<< " first_last " << m_first_last.size()
|
||||
<< std::endl;
|
||||
typedef std::pair<uint32,uint32> first_last;
|
||||
typedef std::pair<uint64,uint64> first_last;
|
||||
tools_vforcit(first_last,m_first_last,it) {
|
||||
uint32 first = (*it).first;
|
||||
uint32 last = (*it).second;
|
||||
uint64 first = (*it).first;
|
||||
uint64 last = (*it).second;
|
||||
m_out << "tools::rroot::branch::stream :"
|
||||
<< " first " << first
|
||||
<< " last " << last
|
||||
@@ -913,9 +915,9 @@ protected:
|
||||
protected:
|
||||
std::ostream& m_out;
|
||||
ifac& m_fac;
|
||||
std::vector< std::pair<uint32,uint32> > m_first_last;
|
||||
std::vector< std::pair<uint64,uint64> > m_first_last;
|
||||
std::map<uint32, std::pair<basket*,bool> > m_baskets;
|
||||
ObjArray<basket> m_streamed_baskets;
|
||||
obj_array<basket> m_streamed_baskets;
|
||||
basket* m__read_basket; //optimization
|
||||
protected:
|
||||
//Object
|
||||
@@ -925,8 +927,8 @@ protected:
|
||||
std::string m_title;
|
||||
|
||||
bool fAutoDelete;
|
||||
ObjArray<branch> m_branches;
|
||||
ObjArray<base_leaf> m_leaves;
|
||||
obj_array<branch> m_branches;
|
||||
obj_array<base_leaf> m_leaves;
|
||||
uint32 fEntryOffsetLen; // Initial Length of fEntryOffset table in the basket buffers
|
||||
uint32 m_write_basket; // Last basket number written
|
||||
uint32 m_entry_number; // Current entry number (last one filled in this branch)
|
||||
|
||||
@@ -265,7 +265,7 @@ public: //branch
|
||||
*/
|
||||
}
|
||||
|
||||
virtual bool find_entry(ifile& a_file,uint32 a_entry,uint32& a_nbytes){
|
||||
virtual bool find_entry(ifile& a_file,uint64 a_entry,uint32& a_nbytes){
|
||||
//The below line will call the upper read_leaves.
|
||||
if(!parent::find_entry(a_file,a_entry,a_nbytes)) return false;
|
||||
|
||||
@@ -285,7 +285,7 @@ public: //branch
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool show(std::ostream& a_out,ifile& a_file,uint32 a_entry){
|
||||
virtual bool show(std::ostream& a_out,ifile& a_file,uint64 a_entry){
|
||||
uint32 n;
|
||||
if(!find_entry(a_file,a_entry,n)) return false;
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_rroot_branch_object
|
||||
#define tools_rroot_branch_object
|
||||
|
||||
#include "branch"
|
||||
|
||||
namespace tools {
|
||||
namespace rroot {
|
||||
|
||||
class branch_object : public branch {
|
||||
typedef branch parent;
|
||||
public:
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::rroot::branch_object");
|
||||
return s_v;
|
||||
}
|
||||
public: //iro
|
||||
virtual void* cast(const std::string& a_class) const {
|
||||
if(void* p = cmp_cast<branch_object>(this,a_class)) return p;
|
||||
return parent::cast(a_class);
|
||||
}
|
||||
virtual const std::string& s_cls() const {return s_class();}
|
||||
public:
|
||||
static cid id_class() {return branch_object_cid();}
|
||||
virtual void* cast(cid a_class) const {
|
||||
if(void* p = cmp_cast<branch_object>(this,a_class)) {return p;}
|
||||
return parent::cast(a_class);
|
||||
}
|
||||
public:
|
||||
virtual bool stream(buffer& a_buffer) {
|
||||
short v;
|
||||
unsigned int s, c;
|
||||
if(!a_buffer.read_version(v,s,c)) return false;
|
||||
if(!parent::stream(a_buffer)) return false;
|
||||
if(!a_buffer.read(fClassName)) return false;
|
||||
if(!a_buffer.check_byte_count(s,c,"TBranchObject")) return false;
|
||||
return true;
|
||||
}
|
||||
public: //branch
|
||||
public:
|
||||
branch_object(std::ostream& a_out,ifac& a_fac)
|
||||
:parent(a_out,a_fac)
|
||||
//,m_obj(0)
|
||||
,fClassName()
|
||||
{}
|
||||
|
||||
virtual ~branch_object(){
|
||||
//delete m_obj;
|
||||
}
|
||||
protected:
|
||||
branch_object(const branch_object& a_from)
|
||||
:iro(a_from),parent(a_from){}
|
||||
branch_object& operator=(const branch_object&){return *this;}
|
||||
public:
|
||||
const std::string& class_name() const {return fClassName;}
|
||||
// iro* object() {return m_obj;}
|
||||
protected:
|
||||
// iro* m_obj;
|
||||
protected:
|
||||
std::string fClassName; //Class name of referenced object
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "ifac"
|
||||
#include "iro"
|
||||
#include "../sout"
|
||||
#include "../mapmanip"
|
||||
#ifdef TOOLS_MEM
|
||||
#include "../mem"
|
||||
#endif
|
||||
@@ -51,14 +52,14 @@ class buffer : public rbuf {
|
||||
typedef std::map<uint32,iro*> obj_map;
|
||||
#endif
|
||||
#ifdef TOOLS_RROOT_OBJ_MAP_OMAP
|
||||
typedef inlib::omap<uint32,iro*> obj_map;
|
||||
typedef omap<uint32,iro*> obj_map;
|
||||
#endif
|
||||
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
|
||||
class obj_map : public inlib::hash_table<uint32,iro*> {
|
||||
typedef inlib::hash_table<uint32,iro*> parent;
|
||||
class obj_map : public hash_table<uint32,iro*> {
|
||||
typedef hash_table<uint32,iro*> parent;
|
||||
protected:
|
||||
virtual unsigned int hash(const uint32& a_key) {
|
||||
return inlib::hash(&a_key,sizeof(uint32));
|
||||
return hash(&a_key,sizeof(uint32));
|
||||
}
|
||||
virtual bool cmp(const uint32& a_key1,const uint32& a_key2) {
|
||||
return a_key1==a_key2?true:false;
|
||||
@@ -119,6 +120,7 @@ public:
|
||||
uint32 size() const {return m_size;}
|
||||
|
||||
void set_map_objs(bool a_value) {m_map_objs = a_value;}
|
||||
bool map_objs() const {return m_map_objs;}
|
||||
protected:
|
||||
// on first_int :
|
||||
static uint32 kNullTag() {return 0;}
|
||||
@@ -256,9 +258,9 @@ protected:
|
||||
if(m_verbose) {
|
||||
std::ios::fmtflags old_flags = m_out.flags();
|
||||
m_out << "tools::rroot::read_class :"
|
||||
<< " first_int " << std::hex << first_int
|
||||
<< ". first_int is position toward object."
|
||||
<< std::endl;
|
||||
<< " first_int " << std::hex << first_int
|
||||
<< ". first_int is position toward object."
|
||||
<< std::endl;
|
||||
m_out.flags(old_flags);
|
||||
}
|
||||
a_bcnt = first_int; //pos toward object.
|
||||
@@ -270,8 +272,16 @@ protected:
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
bool read_object(ifac& a_fac,const ifac::args& a_args,iro*& a_obj){
|
||||
void remove_in_map(iro* a_obj) {
|
||||
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
|
||||
m_out << "tools::rroot::remove_in_map : dummy." << std::endl;
|
||||
#else
|
||||
find_and_remove_value(m_objs,a_obj);
|
||||
#endif
|
||||
}
|
||||
bool read_object(ifac& a_fac,const ifac::args& a_args,iro*& a_obj,bool& a_created){
|
||||
a_obj = 0;
|
||||
a_created = false;
|
||||
|
||||
// before reading object save start position
|
||||
uint32 startpos = (uint32)(m_pos-m_buffer);
|
||||
@@ -368,6 +378,7 @@ public:
|
||||
// << std::endl;
|
||||
|
||||
a_obj = obj;
|
||||
a_created = true;
|
||||
|
||||
} else {
|
||||
m_out << "tools::rroot::buffer::read_object :"
|
||||
@@ -452,6 +463,7 @@ public:
|
||||
}
|
||||
|
||||
a_obj = obj;
|
||||
a_created = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -595,6 +607,101 @@ protected:
|
||||
obj_map m_objs;
|
||||
};
|
||||
|
||||
inline bool dummy_TXxx_pointer_stream(buffer& a_buffer,ifac& a_fac,bool a_del = true) {
|
||||
ifac::args args;
|
||||
iro* obj;
|
||||
bool created;
|
||||
bool status = a_buffer.read_object(a_fac,args,obj,created);
|
||||
if(obj && a_del) {
|
||||
if(created) {
|
||||
if(a_buffer.map_objs()) a_buffer.remove_in_map(obj);
|
||||
delete obj;
|
||||
} else {
|
||||
a_buffer.out() << "dummy_TXxx_pointer_stream : warning : ask to delete an object of class " << sout(obj->s_cls())
|
||||
<< " not created here." << std::endl;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool pointer_stream(buffer& a_buffer,
|
||||
ifac& a_fac,ifac::args& a_args,
|
||||
const std::string& a_T_class,
|
||||
T*& a_obj){
|
||||
iro* obj;
|
||||
bool created;
|
||||
if(!a_buffer.read_object(a_fac,a_args,obj,created)) {
|
||||
a_buffer.out() << "tools::rroot::pointer_stream : read_object failed." << std::endl;
|
||||
a_obj = 0;
|
||||
return false;
|
||||
}
|
||||
if(!obj) {
|
||||
a_obj = 0;
|
||||
} else {
|
||||
a_obj = (T*)obj->cast(a_T_class);
|
||||
if(!a_obj) {
|
||||
a_buffer.out() << "tools::rroot::pointer_stream : "
|
||||
<< " inlib::cast to " << a_T_class << " failed."
|
||||
<< ". Object is a " << obj->s_cls() << "."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool pointer_stream(buffer& a_buffer,
|
||||
ifac& a_fac,ifac::args& a_args,
|
||||
cid a_T_class,
|
||||
T*& a_obj){
|
||||
iro* obj;
|
||||
bool created;
|
||||
if(!a_buffer.read_object(a_fac,a_args,obj,created)) {
|
||||
a_buffer.out() << "tools::rroot::pointer_stream : read_object failed." << std::endl;
|
||||
a_obj = 0;
|
||||
return false;
|
||||
}
|
||||
if(!obj) {
|
||||
a_obj = 0;
|
||||
} else {
|
||||
a_obj = (T*)obj->cast(a_T_class);
|
||||
if(!a_obj) {
|
||||
a_buffer.out() << "tools::rroot::pointer_stream : "
|
||||
<< " inlib::cast to " << a_T_class << " failed."
|
||||
<< ". Object is a " << obj->s_cls() << "."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool pointer_stream(buffer& a_buffer,
|
||||
ifac& a_fac,ifac::args& a_args,T*& a_obj){
|
||||
//return pointer_stream(a_buffer,a_fac,a_args,T::s_class(),a_obj);
|
||||
return pointer_stream(a_buffer,a_fac,a_args,T::id_class(),a_obj);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool fixed_array_stream(buffer& a_buffer,int a_n,T*& a_v){
|
||||
delete [] a_v;
|
||||
a_v = 0;
|
||||
char is_array;
|
||||
if(!a_buffer.read(is_array)) return false;
|
||||
if(!is_array) return true;
|
||||
if(!a_n) return true;
|
||||
a_v = new T[a_n];
|
||||
if(!a_buffer.read_fast_array<T>(a_v,a_n)) {
|
||||
delete [] a_v;
|
||||
a_v = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,16 +14,16 @@ namespace rroot {
|
||||
inline cid base_cid() {return 100;} //must be > cids in ../cids.
|
||||
|
||||
inline cid iros_cid() {return base_cid()+0;}
|
||||
inline cid List_cid() {return base_cid()+1;}
|
||||
inline cid HashList_cid() {return base_cid()+2;}
|
||||
inline cid ObjArray_cid() {return base_cid()+3;}
|
||||
inline cid obj_list_cid() {return base_cid()+1;}
|
||||
inline cid hash_list_cid() {return base_cid()+2;}
|
||||
inline cid obj_array_cid() {return base_cid()+3;}
|
||||
|
||||
inline cid dummy_cid() {return base_cid()+4;}
|
||||
|
||||
inline cid basket_cid() {return base_cid()+5;}
|
||||
inline cid branch_cid() {return base_cid()+6;}
|
||||
inline cid branch_element_cid() {return base_cid()+7;}
|
||||
inline cid tree_item() {return base_cid()+8;}
|
||||
//inline cid tree_item() {return base_cid()+8;}
|
||||
|
||||
inline cid graph_cid() {return base_cid()+9;}
|
||||
inline cid matrix_cid() {return base_cid()+10;}
|
||||
@@ -36,7 +36,10 @@ inline cid streamer_element_cid() {return base_cid()+14;}
|
||||
|
||||
inline cid stl_vector_string_cid() {return base_cid()+16;}
|
||||
|
||||
inline cid Named_cid() {return base_cid()+17;}
|
||||
inline cid named_cid() {return base_cid()+17;}
|
||||
|
||||
inline cid leaf_object_cid() {return base_cid()+18;}
|
||||
inline cid branch_object_cid() {return base_cid()+19;}
|
||||
|
||||
//base for templates :
|
||||
inline cid base_leaf_cid() {return base_cid()+20;} //+12=32
|
||||
|
||||
@@ -175,7 +175,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
void clear_keys() {
|
||||
clear<key>(m_keys);
|
||||
safe_clear<key>(m_keys);
|
||||
}
|
||||
protected:
|
||||
ifile& m_file;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user