diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000000000..9ddfeae907538 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1 @@ +WarningsAsErrors: '*' diff --git a/.travis.yml b/.travis.yml index efd0424f860da..19cf25f0ff922 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,9 @@ addons: &addons cache: apt: true ccache: true +# directories: +# - $BUILD_DEPS + # Do not build our sync branch. branches: @@ -22,38 +25,118 @@ matrix: # Abort all builds on a single failing matrix entry. fast_finish: true + exclude: + # Note: Workaround travis-ci/travis-ci#4681 + # Exclude default job which lacks our included environment variables. + - os: linux + include: # There seems to be a hard limit to how many machines a Travis build will # across all platforms. By interleaving OS X, the hope is to get in the # queue faster while not blocking Linux builds from occuring. - os: linux + env: TOOL=clang-format addons: apt: sources: *sources packages: ['clang-format-3.9'] compiler: clang + - os: linux + env: TOOL=clang-tidy + addons: + apt: + sources: *sources + packages: ['clang-3.9', 'clang-tidy-3.9', 'libstdc++-6-dev'] + compiler: clang + +install: + - | + if [[ $TOOL == 'clang-tidy' ]]; then + export BUILD_DEPS="${TRAVIS_BUILD_DIR}/deps" + mkdir ${BUILD_DEPS} && cd ${BUILD_DEPS} + CMAKE_URL="https://cmake.org/files/v3.6/cmake-3.6.0-Linux-x86_64.tar.gz" + mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake + export PATH=${BUILD_DEPS}/cmake/bin:${PATH} + # Go to the Root directory + cd - + fi + script: +- echo "Copying and generating header files." && echo -en "travis_fold:start:install.headers" +- | + # We need to put in place all relevant headers before running clang-tidy. + if [[ $TOOL == 'clang-tidy' ]]; then + mkdir ../build + cd ../build + export CC=clang-3.9 + export CXX=clang++-3.9 + cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -Dall=On -Dtesting=On -Dx11=Off ../root + # We need to prebuild a minimal set of targets which are responsible for header copy + # or generation. + make -j4 move_headers intrinsics_gen ClangCommentCommandList ClangCommentCommandInfo \ + ClangCommentHTMLNamedCharacterReferences ClangCommentHTMLTagsProperties \ + ClangCommentNodes ClangAttrImpl ClangStmtNodes ClangAttrClasses \ + ClangAttrDump ClangCommentHTMLTags ClangDeclNodes ClangAttrVisitor \ + ClangDiagnosticCommon ClangARMNeon ClangDiagnosticIndexName \ + ClangDiagnosticParse ClangDiagnosticComment ClangDiagnosticFrontend \ + ClangDiagnosticGroups ClangDiagnosticSerialization ClangDiagnosticLex \ + ClangDiagnosticSema ClangAttrList ClangAttrHasAttributeImpl \ + ClangDiagnosticAST ClangDiagnosticDriver ClangDiagnosticAnalysis \ + ClangDriverOptions ClangAttrParserStringSwitches ClangAttrParsedAttrList \ + ClangAttrTemplateInstantiate ClangAttrSpellingListIndex \ + ClangAttrParsedAttrImpl ClangAttrParsedAttrKinds + ln -s $PWD/compile_commands.json $PWD/../root/ + fi +- echo -en 'travis_fold:end:install.headers\\r' + - | if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then - BASE_COMMIT=$(git rev-parse $TRAVIS_BRANCH) - echo "Running clang-format-3.9 against branch $TRAVIS_BRANCH, with hash $BASE_COMMIT" - COMMIT_FILES=$(git diff --name-only $BASE_COMMIT | grep -i -v LinkDef) - RESULT_OUTPUT="$(git-clang-format-3.9 --commit $BASE_COMMIT --diff --binary `which clang-format-3.9` $COMMIT_FILES)" + if [[ $TOOL == 'clang-format' ]]; then + BASE_COMMIT=$(git rev-parse $TRAVIS_BRANCH) + echo "Running clang-format-3.9 against branch $TRAVIS_BRANCH, with hash $BASE_COMMIT" + COMMIT_FILES=$(git diff --name-only $BASE_COMMIT | grep -i -v LinkDef) + RESULT_OUTPUT="$(git-clang-format-3.9 --commit $BASE_COMMIT --diff --binary `which clang-format-3.9` $COMMIT_FILES)" - if [ "$RESULT_OUTPUT" == "no modified files to format" ] \ - || [ "$RESULT_OUTPUT" == "clang-format did not modify any files" ] ; then - - echo "clang-format passed." - exit 0 - else - echo "clang-format failed." - echo "To reproduce it locally please run" - echo -e "\tgit checkout $TRAVIS_BRANCH" - echo -e "\tgit-clang-format --commit $BASE_COMMIT --diff --binary $(which clang-format)" - echo "$RESULT_OUTPUT" - exit 1 + if [ "$RESULT_OUTPUT" == "no modified files to format" ] \ + || [ "$RESULT_OUTPUT" == "clang-format did not modify any files" ] ; then + + echo "clang-format passed." + exit 0 + else + echo "clang-format failed." + echo "To reproduce it locally please run" + echo -e "\tgit checkout $TRAVIS_BRANCH" + echo -e "\tgit-clang-format --commit $BASE_COMMIT --diff --binary $(which clang-format)" + echo "$RESULT_OUTPUT" + exit 1 + fi + elif [[ $TOOL == 'clang-tidy' ]]; then + echo "Running clang-tidy-3.9 only against the changes in branch $TRAVIS_BRANCH." + + cd ../root/ + # Workaround for travis issue: travis-ci/travis-ci#6069 + git remote set-branches --add origin master + git fetch + RESULT_OUTPUT="$(git diff -U0 origin/master | clang-tidy-diff-3.9.py -p1 -clang-tidy-binary $(which clang-tidy-3.9) -checks=-*,clang-analyzer-*)" + if [[ $? -eq 0 ]]; then + echo "clang-tidy passed." + exit 0 + else + echo "To reproduce it locally please run" + echo -e "\tgit checkout $TRAVIS_BRANCH" + echo -e "Command: git diff -U0 $TRAVIS_BRANCH..origin/master | clang-tidy-diff.py -p1 -clang-tidy-binary \$(which clang-tidy) -checks=-*,clang-analyzer-*" + echo "$RESULT_OUTPUT" + exit 1 + fi fi + elif [[ "$TRAVIS_EVENT_TYPE" = "cron" ]] && [[ $TOOL == 'clang-tidy' ]]; then + # We need to ignore our vendor drops. + FILES_REGEX='^.*root\/(?!interpreter\/|core\/clib)' + + echo "Running clang-tidy-3.9 against branch $TRAVIS_BRANCH." + echo "run-clang-tidy-3.9.py -j4 -clang-tidy-binary $(which clang-tidy-3.9) -checks=-*,clang-analyzer-* $FILES_REGEX" + run-clang-tidy-3.9.py -j4 -clang-tidy-binary $(which clang-tidy-3.9) -checks=-*,clang-analyzer-* $FILES_REGEX fi on_failure: diff --git a/bindings/pyroot/src/Converters.cxx b/bindings/pyroot/src/Converters.cxx index 2dd43c1d22149..60f1b092bebd1 100644 --- a/bindings/pyroot/src/Converters.cxx +++ b/bindings/pyroot/src/Converters.cxx @@ -1541,6 +1541,7 @@ namespace { // converter factories for ROOT types typedef std::pair< const char*, ConverterFactory_t > NFp_t; + // clang-format off NFp_t factories_[] = { // factories for built-ins NFp_t( "bool", &CreateBoolConverter ), @@ -1621,8 +1622,10 @@ namespace { NFp_t( "void**", &CreateVoidPtrPtrConverter ), NFp_t( "PyObject*", &CreatePyObjectConverter ), NFp_t( "_object*", &CreatePyObjectConverter ), - NFp_t( "FILE*", &CreateVoidArrayConverter ) + NFp_t( "FILE*", &CreateVoidArrayConverter ), + NFp_t( "Double32_t", &CreateDoubleConverter ) }; + // clang-format on struct InitConvFactories_t { public: diff --git a/core/base/src/TApplication.cxx b/core/base/src/TApplication.cxx index 0b914c5ba6cff..50cd657c0ef35 100644 --- a/core/base/src/TApplication.cxx +++ b/core/base/src/TApplication.cxx @@ -476,8 +476,18 @@ void TApplication::GetOptions(Int_t *argc, char **argv) if (arg) *arg = '\0'; char *dir = gSystem->ExpandPathName(argv[i]); TUrl udir(dir, kTRUE); + // remove options and anchor to check the path + TString sfx = udir.GetFileAndOptions(); + TString fln = udir.GetFile(); + sfx.Replace(sfx.Index(fln), fln.Length(), ""); + TString path = udir.GetFile(); + if (strcmp(udir.GetProtocol(), "file")) { + path = udir.GetUrl(); + path.Replace(path.Index(sfx), sfx.Length(), ""); + } + // 'path' is the full URL without suffices (options and/or anchor) if (arg) *arg = '('; - if (!gSystem->GetPathInfo(dir, &id, &size, &flags, &modtime)) { + if (!gSystem->GetPathInfo(path.Data(), &id, &size, &flags, &modtime)) { if ((flags & 2)) { // if directory set it in fWorkDir if (pwd == "") { @@ -491,7 +501,7 @@ void TApplication::GetOptions(Int_t *argc, char **argv) } else if (size > 0) { // if file add to list of files to be processed if (!fFiles) fFiles = new TObjArray; - fFiles->Add(new TObjString(argv[i])); + fFiles->Add(new TObjString(path.Data())); argv[i] = null; } else { Warning("GetOptions", "file %s has size 0, skipping", dir); diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index d71cb74af0c3a..0167d2ccadd70 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -4468,7 +4468,7 @@ void TCling::Execute(TObject* obj, TClass* cl, TMethod* method, void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE); TClingCallFunc func(fInterpreter,*fNormalizedCtxt); TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo; - func.Init(minfo); + func.Init(*minfo); func.SetArgs(listpar); // Now calculate the 'this' pointer offset for the method // when starting from the class described by cl. diff --git a/core/metacling/src/TClingCallFunc.cxx b/core/metacling/src/TClingCallFunc.cxx index 70d2ed7e88822..cb15cbcd8f1e3 100644 --- a/core/metacling/src/TClingCallFunc.cxx +++ b/core/metacling/src/TClingCallFunc.cxx @@ -2156,18 +2156,23 @@ TClingCallFunc::FactoryMethod() const void TClingCallFunc::Init() { - delete fMethod; - fMethod = 0; + fMethod.reset(); fWrapper = 0; fDecl = nullptr; fMinRequiredArguments = -1; ResetArg(); } -void TClingCallFunc::Init(TClingMethodInfo *minfo) +void TClingCallFunc::Init(const TClingMethodInfo &minfo) { Init(); - fMethod = new TClingMethodInfo(*minfo); + fMethod = std::unique_ptr(new TClingMethodInfo(minfo)); +} + +void TClingCallFunc::Init(std::unique_ptr minfo) +{ + Init(); + fMethod = std::move(minfo); } void *TClingCallFunc::InterfaceMethod() @@ -2291,7 +2296,7 @@ void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, co void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, bool objectIsConst, long *poffset) { - Init(new TClingMethodInfo(fInterp)); + Init(std::unique_ptr(new TClingMethodInfo(fInterp))); if (poffset) { *poffset = 0L; } @@ -2318,7 +2323,7 @@ void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, co void TClingCallFunc::SetFunc(const TClingMethodInfo *info) { - Init(new TClingMethodInfo(*info)); + Init(std::unique_ptr(new TClingMethodInfo(*info))); ResetArg(); if (!fMethod->IsValid()) { return; @@ -2336,7 +2341,7 @@ void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *metho const char *proto, bool objectIsConst, long *poffset, EFunctionMatchMode mode/*=kConversionMatch*/) { - Init(new TClingMethodInfo(fInterp)); + Init(std::unique_ptr(new TClingMethodInfo(fInterp))); if (poffset) { *poffset = 0L; } @@ -2365,7 +2370,7 @@ void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *metho bool objectIsConst, long *poffset, EFunctionMatchMode mode/*=kConversionMatch*/) { - Init(new TClingMethodInfo(fInterp)); + Init(std::unique_ptr(new TClingMethodInfo(fInterp))); if (poffset) { *poffset = 0L; } diff --git a/core/metacling/src/TClingCallFunc.h b/core/metacling/src/TClingCallFunc.h index 713a204df755d..a6e6911afeb47 100644 --- a/core/metacling/src/TClingCallFunc.h +++ b/core/metacling/src/TClingCallFunc.h @@ -62,7 +62,7 @@ class TClingCallFunc { /// ROOT normalized context for that interpreter const ROOT::TMetaUtils::TNormalizedCtxt &fNormCtxt; /// Current method, we own. - TClingMethodInfo* fMethod; + std::unique_ptr fMethod; /// Decl for the method const clang::FunctionDecl *fDecl = nullptr; /// Number of required arguments @@ -135,29 +135,27 @@ class TClingCallFunc { public: - ~TClingCallFunc() { - delete fMethod; - } + ~TClingCallFunc() = default; explicit TClingCallFunc(cling::Interpreter *interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) : fInterp(interp), fNormCtxt(normCtxt), fWrapper(0), fIgnoreExtraArgs(false), fReturnIsRecordType(false) { - fMethod = new TClingMethodInfo(interp); + fMethod = std::unique_ptr(new TClingMethodInfo(interp)); } - explicit TClingCallFunc(TClingMethodInfo &minfo, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) + explicit TClingCallFunc(const TClingMethodInfo &minfo, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) : fInterp(minfo.GetInterpreter()), fNormCtxt(normCtxt), fWrapper(0), fIgnoreExtraArgs(false), fReturnIsRecordType(false) { - fMethod = new TClingMethodInfo(minfo); + fMethod = std::unique_ptr(new TClingMethodInfo(minfo)); } TClingCallFunc(const TClingCallFunc &rhs) : fInterp(rhs.fInterp), fNormCtxt(rhs.fNormCtxt), fWrapper(rhs.fWrapper), fArgVals(rhs.fArgVals), fIgnoreExtraArgs(rhs.fIgnoreExtraArgs), fReturnIsRecordType(rhs.fReturnIsRecordType) { - fMethod = new TClingMethodInfo(*rhs.fMethod); + fMethod = std::unique_ptr(new TClingMethodInfo(*rhs.fMethod)); } TClingCallFunc &operator=(const TClingCallFunc &rhs) = delete; @@ -179,7 +177,8 @@ class TClingCallFunc { void IgnoreExtraArgs(bool ignore) { fIgnoreExtraArgs = ignore; } void Init(); void Init(const clang::FunctionDecl *); - void Init(TClingMethodInfo*); + void Init(const TClingMethodInfo&); + void Init(std::unique_ptr); void Invoke(cling::Value* result = 0) const; void* InterfaceMethod(); bool IsValid() const; diff --git a/etc/http/changes.md b/etc/http/changes.md index 25efd71313d00..247c4bc8733c1 100644 --- a/etc/http/changes.md +++ b/etc/http/changes.md @@ -1,5 +1,13 @@ # JSROOT changelog +## Changes in 5.1.2 +1. Fix - support newest TFormula in TF1 (#127) +2. Fix - ignore NaN value in saved TF1 buffer +3. Fix - correctly treat transparency in geo painter +4. Fix - disable useFontCache for SVG mathjax output +5. Fix - produce PNG image for objects with special symbols in names + + ## Changes in 5.1.1 1. Fix - invoke callback in JSROOT.draw() at proper time 2. Fix - support TGeoHMatrix, produced after GDML conversion @@ -13,11 +21,11 @@ 3. One can hide browser or switch browser kind at any time 4. New 'horizontal' and 'vertical' layouts for object display. One could configure several frames, each divided on sub-frames. - Like display=horiz231 will create three horizontal frames, - divided on 2,3 and 1 sub-frames. -5. One could enable status line where current tooltip info will be shown + Like display=horiz231 will create three horizontal frames, + divided on 2,3 and 1 sub-frames. +5. One could enable status line where current tooltip info will be shown 6. Improve enlarge functionality - now works with all layouts -7. Do not display all canvas tool buttons by default - provide toggle button instead +7. Do not display all canvas tool buttons by default - provide toggle button instead 8. Let move TAxis title, its position now similar to ROOT graphics 9. Support 'col0' option for TH2Poly class to suppress empty bins 10. Implement for TH3 'box2', 'box3', 'glbox2', 'glcol' draw options @@ -27,10 +35,10 @@ 14. Let use quotes in the URL parameters to protect complex arguments with special symbols 15. Introduce direct streamers - like TBasket or TRef Benefit - one can add custom streamers of such kind or reuse existing -16. Handle TMatrixTSym classes in I/O +16. Handle TMatrixTSym classes in I/O 17. Correctly count TH3 statistic in TTree::Draw 18. Recognize bower installation when "bower_components/jsroot/scripts" string - appears in the script path (#120) + appears in the script path (#120) ## Changes in 5.0.3 @@ -44,7 +52,7 @@ 1. Fix - read branch entries as arrays 2. Fix - command submission to THttpServer 3. Fix - let refill statbox also for empty histogram -4. Fix - problem with online TTree::Draw and ROOT6 +4. Fix - problem with online TTree::Draw and ROOT6 ## Changes in 5.0.1 @@ -93,7 +101,7 @@ - d3.js - 4.4.4 - three.js - 84 - jquery - 3.3.1 - - jquery-ui - 1.12.1 + - jquery-ui - 1.12.1 ## Changes in 4.8.2 @@ -119,7 +127,7 @@ ## Changes in 4.8.0 -1. Many improvements in the I/O part +1. Many improvements in the I/O part - support most of STL containers - support TMap and TClonesArray containers - all kind of multidimensional arrays @@ -127,7 +135,7 @@ - supports different versions of class in the same file - support members like ClassName* fField; //[fCnt] - support const char* - - support fixed-size array of TString, TObject and TNamed + - support fixed-size array of TString, TObject and TNamed 2. Many new draw options for different classes are supported: - TGraph - 'z', 'x', '||', '[]', '>', '|>', '5', 'X+', 'Y+' - TH1 - '*', 'L', 'LF2', 'B', 'B1', 'TEXT', 'E0', 'E3', 'E4', 'EX0', 'X+', 'Y+' @@ -135,25 +143,25 @@ - TH2 - 'same' with 'box', 'col', 'cont', 'lego', 'surf' - TH3 - 'scat', use by default - TF1/TF2 - 'nosave' to ignore saved buffer - - TCanvas - logx/y/z, gridx/y, tickx/y + - TCanvas - logx/y/z, gridx/y, tickx/y - THStack - 'lego' and other 3D draw options 3. Implement drawing of TProfile2D, TF2, TGraph2D, TGraph2DErrors and TMarker -4. Fix - correctly place TGAxis relative to frame (when exists) +4. Fix - correctly place TGAxis relative to frame (when exists) 5. When superimpose items, one can specify individual options ...&item=histo1+histo2&opt=hist+e1 ...&item=[histo1,histo2]&opt=[hist,e1] 6. Support loading of TStyle object, providing in URL - ...&style=item_name or ...&style=json_file_name - All values are copied directly to JSROOT.gStyle object. -7. Add callback argument into JSROOT.draw() function. + ...&style=item_name or ...&style=json_file_name + All values are copied directly to JSROOT.gStyle object. +7. Add callback argument into JSROOT.draw() function. Function will be called after drawing of object is completed. - Painter for drawn object will be provided as first argument (or null in case of error). -8. Improve cleanup of JSROOT objects + Painter for drawn object will be provided as first argument (or null in case of error). +8. Improve cleanup of JSROOT objects ## Changes in 4.7.1 1. Workaround for MathJax output - scaling not always works in Firefox -2. Fix - bin scaling for box draw option for TH2 and TH3 histograms +2. Fix - bin scaling for box draw option for TH2 and TH3 histograms 3. Fix - increase points limits for contour plots 4. Fix - position of 3D canvas in WebKit browsers 5. Fix - use abs bin content in RMS calculations @@ -164,19 +172,19 @@ ## Changes in 4.7.0 1. Implement simple TTree::Draw over single leaf (#80) - Support basic types, fixed-size arrays and several vector types + Support basic types, fixed-size arrays and several vector types 2. Display of TEveTrack(s) and TEvePointSet(s) over drawn geometry (drag and drop) Also browsing, toggling, highlight of tracks and hits are done. -3. Let set default geo colors as TGeoManager::DefaultColors() does +3. Let set default geo colors as TGeoManager::DefaultColors() does 4. Let use original ROOT macros to configure visibility of geometry volumes. Like: - &file=files/alice2.root&item=Geometry;1&opt=macro:macros/geomAlice.C + &file=files/alice2.root&item=Geometry;1&opt=macro:macros/geomAlice.C One can set default colors or colors/transperency for selected volumes. Also volume, selected for drawing in the macro, will be used in the JSROOT 5. Support drawing of TH2Poly class with 'col' and 'lego' options -6. Implement 'CONT', 'ARR' and 'SURF' draw options for TH2 class -7. Support basic drawing of TPolyLine class +6. Implement 'CONT', 'ARR' and 'SURF' draw options for TH2 class +7. Support basic drawing of TPolyLine class 8. Interactive axis zooming in 3D with mouse, very much like to 2D -9. Zooming and tool buttons via keyboards +9. Zooming and tool buttons via keyboards ## Changes in 4.6.0 @@ -184,71 +192,71 @@ - support of large (~10M volumes) models, only most significant volumes are shown - one could activate several clip planes (only with WebGL) - interaction with object browser to change visibility flags or focus on selected volume - - support of floating browser for TGeo objects - - intensive use of HTML Worker to offload computation tasks and keep interactivity + - support of floating browser for TGeo objects + - intensive use of HTML Worker to offload computation tasks and keep interactivity - enable more details when changing camera position/zoom - better and faster build of composite shapes 2. Improvements in histograms 3D drawing - all lego options: lego1..lego4, combined with 'fb', 'bb', '0' or 'z' - support axis labels on lego plots - - support lego plots for TH1 + - support lego plots for TH1 3. Improvements in all 3D graphics - upgrade three.js to r79 - use of THREE.BufferGeometry for all components - significant (up to factor 10) performance improvement 4. Implement box and hbox draw options for TH1 class -5. Implement drawing of axes ticks on opposite side (when fTickx/y specified) +5. Implement drawing of axes ticks on opposite side (when fTickx/y specified) 6. Preliminary support of candle plot (many options to be implemented) -7. Update draw attributes (fill/line/position) when monitor objects +7. Update draw attributes (fill/line/position) when monitor objects ## Changes in 4.5.3 1. Fix - position of TFrame in canvas/pad 2. Fix - use histogram fMinimum/fMaximum when creating color palette -3. Fix - correctly draw empty th2 bins when zmin<0 is specified -4. Fix - limit th2 text output size -5. Fix - use histogram fMinimum/fMaximum when drawing z axis in lego plot +3. Fix - correctly draw empty th2 bins when zmin<0 is specified +4. Fix - limit th2 text output size +5. Fix - use histogram fMinimum/fMaximum when drawing z axis in lego plot 6. Fix - error in TGeoCtub shape creation -7. Fix - error in pcon/pgon shapes when Rmin===0 +7. Fix - error in pcon/pgon shapes when Rmin===0 ## Changes in 4.5.1 1. Fix - correctly handle ^2..^9 in TFormula equations -2. Fix - support TMath::Gaus in TFormula -3. Fix - correctly display ^2 and ^3 in SVG text output +2. Fix - support TMath::Gaus in TFormula +3. Fix - correctly display ^2 and ^3 in SVG text output 4. Fix - do not show tooltips for empty TProfile bins 5. Fix - statbox toggling was not working on subpads 6. Fix - positioning of 3D objects in Webkit browsers in complex layouts -7. Fix - difference in TF1 between ROOT5/6 (#54) - +7. Fix - difference in TF1 between ROOT5/6 (#54) + ## Changes in 4.5.0 1. Zooming with mouse wheel 2. Context menus for many different objects attributes are provided -3. Context menu for every drawn object can be activated via toolbar button +3. Context menu for every drawn object can be activated via toolbar button 4. Support browsing of TTask and derived classes (#40) -5. Apply user range for drawing TH1/TH2 histograms, also when superimposed (#44) -6. Implement scaling factor like x10^3 on the vertical axes +5. Apply user range for drawing TH1/TH2 histograms, also when superimposed (#44) +6. Implement scaling factor like x10^3 on the vertical axes 7. Provide shortcut buttons for each subpad 8. Implement simple drawing for TBox, TWbox, TSliderBox classes ## Changes in 4.4.4 -1. Fix - toggling of statbox was not working in all situations +1. Fix - toggling of statbox was not working in all situations 2. Fix - for mouse rect zooming use only left mouse button 3. Fix - correctly draw TH2 with lego option, when histogram has negative bin content -4. Fix - log axis drawing with no visible ticks +4. Fix - log axis drawing with no visible ticks ## Changes in 4.4.3 -1. Fix - wrong selection of TH1 Y axis range when errors are displayed (#44) -2. Fix - apply user range for TH1 X-axis zooming (#44) +1. Fix - wrong selection of TH1 Y axis range when errors are displayed (#44) +2. Fix - apply user range for TH1 X-axis zooming (#44) 3. Fix - protect against pathological case of 1-bin histogram 4. Fix - use error plot by default in TH1 only when positive sumw2 entry exists 5. Fix - for TH2 box draw option draw at least 1px rect for non-empty bin 6. Fix - support transparency (alpha) in TColor (#45) 7. Fix - correct tooltip handling for graphs with lines and markers -8. Fix - interactive zooming in TH2 when doing histogram update +8. Fix - interactive zooming in TH2 when doing histogram update ## Changes in 4.4.2 @@ -260,14 +268,14 @@ ## Changes in 4.4.1 1. Fix - colz palette resize when drawing histogram second time 2. Fix - use embedded in TCanvas color for background color of canvas itself -3. Fix - rotate too long X axis text labels +3. Fix - rotate too long X axis text labels 4. Fix - draw histogram bins on frame boundary -5. Fix - use alternative color for shapes with default black color +5. Fix - use alternative color for shapes with default black color 6. Fix - correctly handle pcon/pgon shape with rmin==rmax on top or bottom side - + ## Changes in 4.4 -1. Fix faces orientation for all TGeo shapes. +1. Fix faces orientation for all TGeo shapes. 2. Improve TGeoTorus creation - handle all parameters combinations 3. Implement TGeoCompositeShape, using ThreeCSG.js 4. Fix problem with color palette when switch to 3D mode (#28) @@ -281,50 +289,50 @@ 9. Provide new tooltip kind - created only when needed (minimizing SVG code) - tooltip can be drawn for every object in the frame - - touch devices are supported + - touch devices are supported 10. Fix - let draw same object on the canvas with different options -11. Create cached list of known class methods. It can be extended by users. +11. Create cached list of known class methods. It can be extended by users. 12. Use of cached methods improves binary I/O performance by 20% 13. Support TGaxis -14. Project now can be obtained via 'bower install jsroot' -15. Support 'scat' and 'text' draw options for TH2 +14. Project now can be obtained via 'bower install jsroot' +15. Support 'scat' and 'text' draw options for TH2 16. Support in binary I/O zipped buffer bigger than 16M 17. Correctly handle in binary I/O pointer on TArray object (like in THnSparseArrayChunk) ## Changes in 4.3 1. Implement TGeoCtub, TGeoParaboloid and TGeoHype shapes -2. Support TGeoTube with Rmin==0 -3. Exclude empty faces in TGeoArb8 -4. Improve TGeoSphere creation - handle all parameters combinations -5. Introduce JSROOT.cleanup() function to safely clear all drawn objects +2. Support TGeoTube with Rmin==0 +3. Exclude empty faces in TGeoArb8 +4. Improve TGeoSphere creation - handle all parameters combinations +5. Introduce JSROOT.cleanup() function to safely clear all drawn objects 6. Fix wrong resize method in 'tabs' and 'collapsible' layouts 7. Fix canvas resize problem (issue #27) 8. Fix zero-height canvas when draw TGeo in collapsible layout 9. Fix problem of simultaneous move TGeo drawings and canvas in flexible layout - + ## Changes in 4.2 -1. Significant performance improvements in 3D drawings - TGeo/TH2/TH3 +1. Significant performance improvements in 3D drawings - TGeo/TH2/TH3 2. Implement TGeoPara, TGeoGtra, TGeoXtru and TGeoEltu shapes -3. Optimize (reduce vertices number) for others TGeo shapes -4. Correct rotation/translation/scaling of TGeo nodes -5. Workaround for axis reflection (not directly supported in three.js) +3. Optimize (reduce vertices number) for others TGeo shapes +4. Correct rotation/translation/scaling of TGeo nodes +5. Workaround for axis reflection (not directly supported in three.js) 6. Support array of objects in I/O (like in TAxis3D) 7. Correct reading of multi-dim arrays like Double_t fXY[8][2]; -8. Provide canvas toolbar for actions like savepng or unzoom -9. Implement JSROOT.resize() function to let resize drawing after changes in page layout -10. Fix error with title display/update - +8. Provide canvas toolbar for actions like savepng or unzoom +9. Implement JSROOT.resize() function to let resize drawing after changes in page layout +10. Fix error with title display/update + ## Changes in 4.1 1. Introduce object inspector - one could browse object members of any class 2. Let draw sub-items from TCanvas list of primitives like sub-pad or TLatex -3. Provide possibility to save drawn SVG canvas as PNG -4. TGraph drawing optimization - limit number of drawn points +3. Provide possibility to save drawn SVG canvas as PNG +4. TGraph drawing optimization - limit number of drawn points 5. Implement painter for TPolyMarker3D -6. Improve drawing and update of TMultiGraph -7. Reorganize 3D drawing of TH2/TH3 histograms, allow to mix 2D and 3D display together +6. Improve drawing and update of TMultiGraph +7. Reorganize 3D drawing of TH2/TH3 histograms, allow to mix 2D and 3D display together 8. Support overlay of 3D graphic over SVG canvas (used for IE) 9. Fix problems and improve flex(ible) layout @@ -340,12 +348,12 @@ 3. Significant (factor 4) I/O performance improvement: - use ArrayBuffer class in HTTP requests instead of String - use native arrays (like Int32Array) for array data members - - highly optimize streamer infos handling + - highly optimize streamer infos handling 4. TH2 drawing optimization: - if there are too many non-empty bins, combine them together - when zoom-in, all original bins will be displayed separately - let draw big TH2 histogram faster than in 1 sec - - optimization can be disabled by providing '&optimize=0' in URL + - optimization can be disabled by providing '&optimize=0' in URL 5. TF1 drawing optimization: - function 'compiled' only once 6. Reorganize scripts structure: @@ -353,12 +361,12 @@ - TH2, TF1, THStack and TMultiGraph painters moved into JSRootPainter.more.js script - reduce size of scripts required for default functionality 7. Update all basic libraries: - - d3.js - v3.5.9, - - jquery.js - v2.1.4, - - jquery-ui.js - v1.11.4, - - three.js - r73 + - d3.js - v3.5.9, + - jquery.js - v2.1.4, + - jquery-ui.js - v1.11.4, + - three.js - r73 8. Implement ROOT6-like color palettes: - - all palettes in range 51...112 are implemented + - all palettes in range 51...112 are implemented - by default palette 57 is used - one could change default palette with '&palette=111' in URL - or palette can be specified in draw option like '&opt=colz,pal77' @@ -366,14 +374,14 @@ ## Changes in 3.9 1. Support non-equidistant bins for TH1/TH2 objects. -2. Display entries count from histo.fEntries member, only when not set use computed value +2. Display entries count from histo.fEntries member, only when not set use computed value 3. Support italic and bold text when used with MathJax 4. Improve TF1 drawing - support exp function in TFormula, fix errors with logx scale, enable zoom-in, (re)calculate function points when zooming 5. Support several columns in TLegend 6. Introduce context menus for x/y axis, add some items similar to native ROOT menus -7. Introduce context menu for TPaveStats, let switch single elements in the box -8. Enable usage of all context menus on touch devices -9. Implement JSROOT.Math.Prob function, provides probability value in stat box +7. Introduce context menu for TPaveStats, let switch single elements in the box +8. Enable usage of all context menus on touch devices +9. Implement JSROOT.Math.Prob function, provides probability value in stat box 10. Introduce context menu for color palette (z axis) 11. Implement col0 and col0z draw option for TH2 histograms, similar to ROOT6 @@ -382,61 +390,61 @@ 1. Let use HTML element pointer in JSROOT.draw function like: JSROOT.draw(document.getElementsByTagName("div")[0], obj, "hist"); Normally unique identifier was used before, which is not required any longer. - Of course, old functionality with element identifier will work as well. + Of course, old functionality with element identifier will work as well. 2. TreePlayer can also be used for trees, which not yet read from the file. - Requires appropriate changes in TRootSniffer class. -3. Fix error in I/O with members like: `Double_t *fArr; //[fN]` + Requires appropriate changes in TRootSniffer class. +3. Fix error in I/O with members like: `Double_t *fArr; //[fN]` 4. Introduce JSROOT.OpenFile function. It loads I/O functionality automatically, therefore can be used directly after loading JSRootCore.js script 5. Same is done with JSROOT.draw function. It is defined in the JSRootCore.js - and can be used directly. Makes usage of JSROOT easier + and can be used directly. Makes usage of JSROOT easier 6. Introduce JSRootPainter.more.js script, where painters for auxiliary classes will be implemented. -7. Implement painter for TEllipse, TLine, TArrow classes -8. Fix several problems with markers drawing; implement plus, asterisk, mult symbols. +7. Implement painter for TEllipse, TLine, TArrow classes +8. Fix several problems with markers drawing; implement plus, asterisk, mult symbols. 9. Implement custom layout, which allows to configure user-defined layout for displayed objects -10. Fix errors with scaling of axis labels. -11. Support also Y axis with custom labels like: http://jsroot.gsi.de/dev/?nobrowser&file=../files/atlas.root&item=LEDShapeHeightCorr_Gain0;1&opt=col +10. Fix errors with scaling of axis labels. +11. Support also Y axis with custom labels like: http://jsroot.gsi.de/dev/?nobrowser&file=../files/atlas.root&item=LEDShapeHeightCorr_Gain0;1&opt=col ## Changes in 3.7 1. Support of X axis with custom labels like: http://jsroot.gsi.de/dev/?nobrowser&json=../files/hist_xlabels.json 2. Extend functionality of JSROOT.addDrawFunc() function. One could register type-specific `make_request` and `after_request` functions; `icon`, `prereq`, `script`, `monitor` properties. - This let add more custom elements to the generic gui, implemented with JSROOT.HierarchyPainter + This let add more custom elements to the generic gui, implemented with JSROOT.HierarchyPainter 3. Provide full support of require.js. One could load now JSRootCore.js script like: - + After this several modules are defined and can be used with syntax like: - + require(['JSRootPainter'], function(jsroot) { /*any user code*/}); - - Also inside JSROOT require.js used to load all dependencies. + + Also inside JSROOT require.js used to load all dependencies. ## Changes in 3.6 1. Try to provide workaround for websites where require.js already loaded. - This makes problem by direct loading of jquery and jquery-ui -2. Provide workaround for older version of jquery-ui + This makes problem by direct loading of jquery and jquery-ui +2. Provide workaround for older version of jquery-ui 3. Prompt for input of command arguments 4. After command execution one could automatically reload hierarchy (_hreload property) or - update view of displayed object (_update_item property) + update view of displayed object (_update_item property) 5. Use HiearchyPainter for implementing draw.htm. This let us handle - all different kinds of extra attributes in central place + all different kinds of extra attributes in central place 6. Fix problem in tabs layout - new tab should be add to direct child 7. When drawing several tabs, activate frame before drawing - only then real frame size will be set -8. Fix problem with GetBBox - it only can be used for visible elements in mozilla. +8. Fix problem with GetBBox - it only can be used for visible elements in mozilla. 9. Support drawing of fit parameters in stat box, use (as far as possible) stat and - fit format for statistic display -10. Implement 'g' formatting kind for stat box output - one need to checks - significant digits when producing output. + fit format for statistic display +10. Implement 'g' formatting kind for stat box output - one need to checks + significant digits when producing output. 11. Support new draw options for TGraph: 'C', 'B1', '0', '2', '3', '4', '[]' 12. Primary support for STL containers in IO part. Allows to read ROOT6 TF1. 13. Full support of TGraphBentErrors 14. Support objects drawing from JSON files in default user interface, including - monitoring. One could open file from link like: https://root.cern.ch/js/dev/?json=demo/canvas_tf1.json + monitoring. One could open file from link like: https://root.cern.ch/js/dev/?json=demo/canvas_tf1.json 15. Introduce JSROOT.FFormat function to convert numeric values into string according format like 6.4g or 5.7e. Used for statistic display. @@ -444,17 +452,17 @@ ## Changes in 3.5 1. Fix error in vertical text alignment 2. Many improvements in TPaletteAxis drawing - draw label, avoid too large ticks. -3. Fix error with col drawing - bin with maximum value got wrong color -4. Test for existing jquery.js, jquery-ui.js and d3.js libraries, reuse when provided +3. Fix error with col drawing - bin with maximum value got wrong color +4. Test for existing jquery.js, jquery-ui.js and d3.js libraries, reuse when provided 5. Fix several I/O problems; now one could read files, produced in Geant4 -6. Implement 'e2' drawing option for TH1 class, +6. Implement 'e2' drawing option for TH1 class, use by default 'e' option when TH1 has non-empty fSumw2 -7. Reuse statistic from histogram itself, when no axis selection done +7. Reuse statistic from histogram itself, when no axis selection done 8. Support log/lin z scale for color drawing -9. Implement interactive z-scale selection on TPaletteAxis +9. Implement interactive z-scale selection on TPaletteAxis 10. Allow to redraw item with other draw options (before one should clear drawings) 11. Several improvements in THttpServer user interface - repair hierarchy reload, - hide unsupported context menu entries, status line update + hide unsupported context menu entries, status line update ## Changes in 3.4 @@ -622,7 +630,7 @@ Such link is best possibility to integrate display into different HTML pages, using `` 15. Remove 'JSROOTIO.' prefix from _typename. Now real class name is used. 16. Use in all scripts JSROOT as central 'namespace' diff --git a/etc/http/scripts/JSRootCore.js b/etc/http/scripts/JSRootCore.js index 68a732f56efa3..7947c521ac5bf 100644 --- a/etc/http/scripts/JSRootCore.js +++ b/etc/http/scripts/JSRootCore.js @@ -57,7 +57,7 @@ 'MathJax': { exports: 'MathJax', init: function () { - MathJax.Hub.Config({ TeX: { extensions: ["color.js"] }, SVG: { mtextFontInherit: true } }); + MathJax.Hub.Config({ TeX: { extensions: ["color.js"] }, SVG: { mtextFontInherit: true, minScaleAdjust: 100, matchFontHeight: true, useFontCache: false } }); MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT; VARIANT["normal"].fonts.unshift("MathJax_SansSerif"); @@ -92,7 +92,7 @@ } } (function(JSROOT) { - JSROOT.version = "5.1.1 23/03/2017"; + JSROOT.version = "5.1.2 21/04/2017"; JSROOT.source_dir = ""; JSROOT.source_min = false; @@ -1535,13 +1535,17 @@ m.evalPar = function(x, y) { if (! ('_func' in this) || (this._title !== this.fTitle)) { - var _func = this.fTitle, isformula = false; + var _func = this.fTitle, isformula = false, pprefix = "["; if (_func === "gaus") _func = "gaus(0)"; - if (this.fFormula && typeof this.fFormula.fFormula == "string") + if (this.fFormula && typeof this.fFormula.fFormula == "string") { if (this.fFormula.fFormula.indexOf("[](double*x,double*p)")==0) { - isformula = true; + isformula = true; pprefix = "p["; _func = this.fFormula.fFormula.substr(21); + } else { + _func = this.fFormula.fFormula; + pprefix = "[p"; } + } if ('formulas' in this) for (var i=0;ithis.maxdepth) this.maxdepth = sublevel; var chlds = null; if (kind===0) diff --git a/etc/http/scripts/JSRootGeoPainter.js b/etc/http/scripts/JSRootGeoPainter.js index 42ecb3f15fcb4..087ea30af2822 100644 --- a/etc/http/scripts/JSRootGeoPainter.js +++ b/etc/http/scripts/JSRootGeoPainter.js @@ -1179,6 +1179,7 @@ // keep full stack of nodes mesh.stack = entry.stack; + mesh.renderOrder = this._clones.maxdepth - entry.stack.length; // order of transparancy handling obj3d.add(mesh); diff --git a/etc/http/scripts/JSRootPainter.jquery.js b/etc/http/scripts/JSRootPainter.jquery.js index 3f73b3cc9abf1..ee28214ce1979 100644 --- a/etc/http/scripts/JSRootPainter.jquery.js +++ b/etc/http/scripts/JSRootPainter.jquery.js @@ -818,9 +818,10 @@ var jmain = $("#"+this.gui_div+" .jsroot_browser"), top = 7, left = 7; if (this.browser_visible) { - var area = jmain.find(".jsroot_browser_area"); - top = area.offset().top + 7; - left = area.offset().left + area.innerWidth() - 27; + var area = jmain.find(".jsroot_browser_area"), + off0 = jmain.offset(), off1 = area.offset(); + top = off1.top - off0.top + 7; + left = off1.left - off0.left + area.innerWidth() - 27; } jmain.find(".jsroot_browser_btns") diff --git a/etc/http/scripts/JSRootPainter.js b/etc/http/scripts/JSRootPainter.js index 201e783f6217d..90dc230a3f7da 100644 --- a/etc/http/scripts/JSRootPainter.js +++ b/etc/http/scripts/JSRootPainter.js @@ -1384,8 +1384,8 @@ // set attributes for debugging if (this.draw_object!==null) { - this.draw_g.attr('objname', this.draw_object.fName || "name"); - this.draw_g.attr('objtype', this.draw_object._typename || "type"); + this.draw_g.attr('objname', encodeURI(this.draw_object.fName || "name")); + this.draw_g.attr('objtype', encodeURI(this.draw_object._typename || "type")); } return this.draw_g; @@ -1864,9 +1864,9 @@ var id = "pat_" + this.pattern + "_" + this.colorindx; - var defs = svg.select('defs'); + var defs = svg.select('.canvas_defs'); if (defs.empty()) - defs = svg.insert("svg:defs",":first-child"); + defs = svg.insert("svg:defs",":first-child").attr("class","canvas_defs"); var line_color = this.color; this.color = "url(#" + id + ")"; diff --git a/etc/http/scripts/JSRootPainter.more.js b/etc/http/scripts/JSRootPainter.more.js index 814bffaa88190..b68e58874999e 100644 --- a/etc/http/scripts/JSRootPainter.more.js +++ b/etc/http/scripts/JSRootPainter.more.js @@ -975,8 +975,9 @@ var xx = xmin + dx*n; // check if points need to be displayed at all, keep at least 4-5 points for Bezier curves if ((gxmin !== gxmax) && ((xx + 2*dx < gxmin) || (xx - 2*dx > gxmax))) continue; + var yy = tf1.fSave[n]; - res.push({ x: xx, y: tf1.fSave[n] }); + if (!isNaN(yy)) res.push({ x : xx, y : yy }); } return res; } @@ -1012,7 +1013,7 @@ var xmin = 0, xmax = 1, ymin = 0, ymax = 1, bins = this.CreateBins(true); - if (bins!==null) { + if ((bins!==null) && (bins.length > 0)) { xmin = xmax = bins[0].x; ymin = ymax = bins[0].y; @@ -1032,7 +1033,15 @@ tf1 = this.GetObject(); histo.fName = tf1.fName + "_hist"; - histo.fTitle = tf1.fTitle; + if (tf1.fTitle.indexOf(';')!==0) { + var array = tf1.fTitle.split(';'); + histo.fTitle = array[0]; + if (array.length>1) + histo.fXaxis.fTitle = array[1]; + if (array.length>2) + histo.fYaxis.fTitle = array[2]; + } + else histo.fTitle = tf1.fTitle; histo.fXaxis.fXmin = xmin; histo.fXaxis.fXmax = xmax; diff --git a/etc/http/scripts/mathjax_config.js b/etc/http/scripts/mathjax_config.js index bc31b6d93876c..43456cd07bb35 100644 --- a/etc/http/scripts/mathjax_config.js +++ b/etc/http/scripts/mathjax_config.js @@ -1,4 +1,4 @@ -MathJax.Hub.Config({ TeX: { extensions: ["color.js"] }, SVG: { mtextFontInherit: true, minScaleAdjust: 100, matchFontHeight: true } }); +MathJax.Hub.Config({ TeX: { extensions: ["color.js"] }, SVG: { mtextFontInherit: true, minScaleAdjust: 100, matchFontHeight: true, useFontCache: false } }); MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT; VARIANT["normal"].fonts.unshift("MathJax_SansSerif"); diff --git a/graf2d/gpad/src/TCanvas.cxx b/graf2d/gpad/src/TCanvas.cxx index 71899f79846be..44197d34a54a3 100644 --- a/graf2d/gpad/src/TCanvas.cxx +++ b/graf2d/gpad/src/TCanvas.cxx @@ -1236,8 +1236,7 @@ void TCanvas::HandleInput(EEventType event, Int_t px, Int_t py) fSelected->ExecuteEvent(event, px, py); gVirtualX->Update(); - - if (!fSelected->InheritsFrom(TAxis::Class())) { + if (fSelected && !fSelected->InheritsFrom(TAxis::Class())) { Bool_t resize = kFALSE; if (fSelected->InheritsFrom(TBox::Class())) resize = ((TBox*)fSelected)->IsBeingResized(); diff --git a/math/smatrix/test/testSMatrix.cxx b/math/smatrix/test/testSMatrix.cxx index 07d46caef1458..36290ca4e2207 100644 --- a/math/smatrix/test/testSMatrix.cxx +++ b/math/smatrix/test/testSMatrix.cxx @@ -1051,6 +1051,9 @@ int test18() { int tol = 10; #ifdef __FAST_MATH__ tol = 16; +#endif +#ifdef __arm__ + tol = 60; #endif for (int i = 0; i < 7; ++i) { int iiret = compare(Id(i,i),1.,"inv result",tol); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f3b8de02203da..54abb6a6a7924 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -154,9 +154,9 @@ endif() if(ROOT_tmva_FOUND) ROOT_EXECUTABLE(stressTMVA stressTMVA.cxx LIBRARIES TMVA) - ROOT_ADD_TEST(test-stresstmva COMMAND stressTMVA -b LABELS longtest) + ROOT_ADD_TEST(test-stresstmva COMMAND stressTMVA -b LABELS longtest TIMEOUT 1800) ROOT_ADD_TEST(test-stresstmva-interpreted COMMAND ${ROOT_root_CMD} -b -q -l ${CMAKE_CURRENT_SOURCE_DIR}/stressTMVA.cxx - FAILREGEX "FAILED|Error in" DEPENDS test-stresstmva) + FAILREGEX "FAILED|Error in" DEPENDS test-stresstmva TIMEOUT 1800) endif() #--stressMathMore---------------------------------------------------------------------------------- diff --git a/tree/tree/inc/TTree.h b/tree/tree/inc/TTree.h index 3f00162f93fc1..457878241dd06 100644 --- a/tree/tree/inc/TTree.h +++ b/tree/tree/inc/TTree.h @@ -132,7 +132,8 @@ class TTree : public TNamed, public TAttLine, public TAttFill, public TAttMarker Bool_t fCacheUserSet; ///> fSortedBranches; ///> fSortedBranches; /// fSeqBranches; /// fIMTTotBytes; /// fIMTZipBytes; /// 0 && filename.Index("/") > pIdx) { - // filename has a url format "xxx://" - // decide if to do full search for url query and fragment identifiers - isUrl = kTRUE; - if (wildcards) { - TUrl url(name); - if (url.IsValid()) { - TString proto = url.GetProtocol(); - if (proto == "http" || proto == "https") { - isUrlDoFull = kTRUE; - } - } - } else { - isUrlDoFull = kTRUE; - } - } - - if (isUrlDoFull) { - pIdx = filename.Index("?"); - if (pIdx != kNPOS) { - query = filename(pIdx,filename.Length()-pIdx); - suffix = filename(pIdx, filename.Length()-pIdx); - filename.Remove(pIdx); - } - pIdx = query.Index("#"); - if (pIdx != kNPOS) { - treename = query(pIdx+1,query.Length()-pIdx-1); - query.Remove(pIdx); - if (query.Length() == 1) { - // was only followed by the fragment - query.Clear(); - } - } - } - - if (treename.IsNull()) { - Ssiz_t dotSlashPos = kNPOS; - pIdx = filename.Index(".root"); - while(pIdx != kNPOS) { - dotSlashPos = pIdx; - pIdx = filename.Index(".root",dotSlashPos+1); - } - if (dotSlashPos != kNPOS && filename[dotSlashPos+5]!='/') { - // We found the 'last' .root in the name and it is not followed by - // a '/', so the tree name is _not_ specified in the name. - dotSlashPos = kNPOS; - } - if (dotSlashPos != kNPOS) { - // Copy the tree name specification and remove it from filename - treename = filename(dotSlashPos+6,filename.Length()-dotSlashPos-6); - suffix.Prepend(filename(dotSlashPos+5, filename.Length()-dotSlashPos-5)); - filename.Remove(dotSlashPos+5); - } - if (isUrl && !isUrlDoFull) { - pIdx = treename.Index("?"); - if (pIdx != kNPOS) { - query = treename(pIdx,treename.Length()-pIdx); - treename.Remove(pIdx); - } - } + // General case + TUrl url(name); + + // Extract query (and treename, if any) + query.Form("?%s", url.GetOptions()); + treename = url.GetAnchor(); + + // Save suffix, if any + suffix = url.GetFileAndOptions(); + TString fn = url.GetFile(); + suffix.Replace(suffix.Index(fn), fn.Length(), ""); + // Remove it from the file name + filename.Remove(filename.Index(fn) + fn.Length()); + + // Special case: [...]file.root/treename + static const char *dotr = ".root/"; + static Ssiz_t dotrl = strlen(dotr); + pIdx = filename.Index(dotr); + if (pIdx != kNPOS) { + treename = filename(pIdx + dotrl, filename.Length()); + filename.Remove(pIdx + dotrl - 1); } } diff --git a/tree/tree/src/TTree.cxx b/tree/tree/src/TTree.cxx index 3f9f1bce9b237..160df20f2e4ff 100644 --- a/tree/tree/src/TTree.cxx +++ b/tree/tree/src/TTree.cxx @@ -403,6 +403,7 @@ End_Macro #include #include #include +#include #ifdef R__USE_IMT #include "ROOT/TThreadExecutor.hxx" @@ -4862,7 +4863,7 @@ Int_t TTree::FlushBaskets() const #ifdef R__USE_IMT if (fIMTEnabled) { - if (fSortedBranches.empty()) { const_cast(this)->InitializeSortedBranches(); } + if (fSortedBranches.empty()) { const_cast(this)->InitializeBranchLists(false); } BoolRAIIToggle sentry(fIMTFlush); fIMTZipBytes.store(0); @@ -5339,7 +5340,15 @@ Int_t TTree::GetEntry(Long64_t entry, Int_t getall) #ifdef R__USE_IMT if (ROOT::IsImplicitMTEnabled() && fIMTEnabled) { - if (fSortedBranches.empty()) InitializeSortedBranches(); + if (fSortedBranches.empty()) InitializeBranchLists(true); + + // Count branches are processed first and sequentially + for (auto branch : fSeqBranches) { + nb = branch->GetEntry(entry, getall); + if (nb < 0) break; + nbytes += nb; + } + if (nb < 0) return nb; // Enable this IMT use case (activate its locks) ROOT::Internal::TParBranchProcessingRAII pbpRAII; @@ -5380,14 +5389,14 @@ Int_t TTree::GetEntry(Long64_t entry, Int_t getall) }; ROOT::TThreadExecutor pool; - pool.Foreach(mapFunction, nbranches); + pool.Foreach(mapFunction, nbranches - fSeqBranches.size()); if (errnb < 0) { nb = errnb; } else { // Save the number of bytes read by the tasks - nbytes = nbpar; + nbytes += nbpar; // Re-sort branches if necessary if (++fNEntriesSinceSorting == kNEntriesResort) { @@ -5426,26 +5435,56 @@ Int_t TTree::GetEntry(Long64_t entry, Int_t getall) return nbytes; } + //////////////////////////////////////////////////////////////////////////////// -/// Initializes the vector of top-level branches and sorts it by branch size. +/// Divides the top-level branches into two vectors: (i) branches to be +/// processed sequentially and (ii) branches to be processed in parallel. +/// Even if IMT is on, some branches might need to be processed first and in a +/// sequential fashion: in the parallelization of GetEntry, those are the +/// branches that store the size of another branch for every entry +/// (e.g. the size of an array branch). If such branches were processed +/// in parallel with the rest, there could be two threads invoking +/// TBranch::GetEntry on one of them at the same time, since a branch that +/// depends on a size (or count) branch will also invoke GetEntry on the latter. +/// \param[in] checkLeafCount True if we need to check whether some branches are +/// count leaves. -void TTree::InitializeSortedBranches() +void TTree::InitializeBranchLists(bool checkLeafCount) { Int_t nbranches = fBranches.GetEntriesFast(); + + // The branches to be processed sequentially are those that are the leaf count of another branch + if (checkLeafCount) { + for (Int_t i = 0; i < nbranches; i++) { + TBranch* branch = (TBranch*)fBranches.UncheckedAt(i); + auto leafCount = ((TLeaf*)branch->GetListOfLeaves()->At(0))->GetLeafCount(); + if (leafCount) { + auto countBranch = leafCount->GetBranch(); + if (std::find(fSeqBranches.begin(), fSeqBranches.end(), countBranch) == fSeqBranches.end()) { + fSeqBranches.push_back(countBranch); + } + } + } + } + + // Any branch that is not a leaf count can be safely processed in parallel when reading for (Int_t i = 0; i < nbranches; i++) { Long64_t bbytes = 0; TBranch* branch = (TBranch*)fBranches.UncheckedAt(i); - if (branch) bbytes = branch->GetTotBytes("*"); - fSortedBranches.emplace_back(bbytes, branch); + if (std::find(fSeqBranches.begin(), fSeqBranches.end(), branch) == fSeqBranches.end()) { + bbytes = branch->GetTotBytes("*"); + fSortedBranches.emplace_back(bbytes, branch); + } } + // Initially sort parallel branches by size std::sort(fSortedBranches.begin(), fSortedBranches.end(), [](std::pair a, std::pair b) { return a.first > b.first; }); - for (Int_t i = 0; i < nbranches; i++) { + for (size_t i = 0; i < fSortedBranches.size(); i++) { fSortedBranches[i].first = 0LL; } } @@ -5455,8 +5494,7 @@ void TTree::InitializeSortedBranches() void TTree::SortBranchesByTime() { - Int_t nbranches = fBranches.GetEntriesFast(); - for (Int_t i = 0; i < nbranches; i++) { + for (size_t i = 0; i < fSortedBranches.size(); i++) { fSortedBranches[i].first *= kNEntriesResortInv; } @@ -5466,7 +5504,7 @@ void TTree::SortBranchesByTime() return a.first > b.first; }); - for (Int_t i = 0; i < nbranches; i++) { + for (size_t i = 0; i < fSortedBranches.size(); i++) { fSortedBranches[i].first = 0LL; } } diff --git a/tutorials/eve/calorimeters.C b/tutorials/eve/calorimeters.C index 442f15a971899..8eb66a5cc7571 100644 --- a/tutorials/eve/calorimeters.C +++ b/tutorials/eve/calorimeters.C @@ -8,6 +8,27 @@ /// \author Alja Mrak-Tadel #include "TEveProjections.h" +#include "TSystem.h" +#include "TEveCalo.h" +#include "TEveWindow.h" +#include "TEveManager.h" +#include "TEveBrowser.h" +#include "TEveProjectionAxes.h" +#include "TEveScene.h" +#include "TEveViewer.h" +#include "TEveTrans.h" +#include "TEveCaloLegoOverlay.h" +#include "TEveLegoEventHandler.h" +#include "TEveGedEditor.h" +#include "TEveJetCone.h" + +#include "TGLWidget.h" +#include "TGLViewer.h" +#include "TGTab.h" + +#include "TFile.h" +#include "TAxis.h" + const char* histFile = "http://amraktad.web.cern.ch/amraktad/cms_calo_hist.root"; @@ -21,7 +42,7 @@ void add_jet(TEveElement*, const char*, Float_t, Float_t, Float_t, Float_t); void calorimeters() { - gSystem->IgnoreSignal(kSigSegmentationViolation, true); + // gSystem->IgnoreSignal(kSigSegmentationViolation, true); TEveManager::Create(); // event data @@ -89,7 +110,6 @@ TEveCaloLego* MakeCaloLego(TEveCaloData* data, TEveWindowSlot* slot) TEveScene* s; if (slot) { - TEveViewer* v; TEveScene* s; MakeViewerScene(slot, v, s); } else { v = gEve->GetDefaultViewer();