Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
athena
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
EIC
detectors
athena
Commits
b4ea1bf0
Commit
b4ea1bf0
authored
3 years ago
by
Wouter Deconinck
Browse files
Options
Downloads
Patches
Plain Diff
Move fieldmap download to FileLoader plugin
parent
e7cbbff1
No related branches found
No related tags found
2 merge requests
!329
Master into deathvalley
,
!322
Move fieldmap download to FileLoader plugin
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/FieldMapBrBz.cpp
+7
-8
7 additions, 8 deletions
src/FieldMapBrBz.cpp
src/FileLoader.cpp
+2
-117
2 additions, 117 deletions
src/FileLoader.cpp
src/FileLoaderHelper.h
+143
-0
143 additions, 0 deletions
src/FileLoaderHelper.h
with
152 additions
and
125 deletions
src/FieldMapBrBz.cpp
+
7
−
8
View file @
b4ea1bf0
#include
<DD4hep/DetFactoryHelper.h>
#include
<DD4hep/FieldTypes.h>
#include
<DD4hep/Printout.h>
#include
<XML/Utilities.h>
#include
<cstdlib>
...
...
@@ -12,6 +13,8 @@
#include
<tuple>
namespace
fs
=
std
::
filesystem
;
#include
"FileLoaderHelper.h"
using
namespace
dd4hep
;
...
...
@@ -185,20 +188,16 @@ static Ref_t create_field_map_brbz(Detector & /*lcdd*/, xml::Handle_t handle)
std
::
string
field_map_file
=
x_par
.
attr
<
std
::
string
>
(
_Unicode
(
field_map
));
std
::
string
field_map_url
=
x_par
.
attr
<
std
::
string
>
(
_Unicode
(
url
));
EnsureFileFromURLExists
(
field_map_url
,
field_map_file
);
double
field_map_scale
=
x_par
.
attr
<
double
>
(
_Unicode
(
scale
));
if
(
!
fs
::
exists
(
fs
::
path
(
field_map_file
))
)
{
auto
ret
=
std
::
system
((
"mkdir -p fieldmaps && "
"curl --retry 5 -f "
+
field_map_url
+
" -o "
+
field_map_file
).
c_str
());
if
(
!
fs
::
exists
(
fs
::
path
(
field_map_file
)))
{
std
::
cerr
<<
"ERROR: file, "
<<
field_map_file
<<
", does not exist
\n
"
;
printout
(
ERROR
,
"FieldMapBrBz"
,
"file "
+
field_map_file
+
" does not exist"
);
printout
(
ERROR
,
"FieldMapBrBz"
,
"use a FileLoader plugin before the field element"
);
std
::
quick_exit
(
1
);
}
}
auto
map
=
new
FieldMapBrBz
(
field_type
);
map
->
Configure
(
r_dim
.
rmin
(),
r_dim
.
rmax
(),
r_dim
.
step
(),
z_dim
.
zmin
(),
z_dim
.
zmax
(),
z_dim
.
step
());
...
...
This diff is collapsed.
Click to expand it.
src/FileLoader.cpp
+
2
−
117
View file @
b4ea1bf0
...
...
@@ -11,7 +11,7 @@
#include
<cstdlib>
#include
<string>
namespace
fs
=
std
::
filesystem
;
#include
"FileLoaderHelper.h"
using
namespace
dd4hep
;
...
...
@@ -58,122 +58,7 @@ long load_file(
return
0
;
}
// parse cache for environment variables
auto
pos
=
std
::
string
::
npos
;
while
((
pos
=
cache
.
find
(
'$'
))
!=
std
::
string
::
npos
)
{
auto
after
=
cache
.
find_first_not_of
(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"_"
,
pos
+
1
);
if
(
after
==
std
::
string
::
npos
)
after
=
cache
.
size
();
// cache ends on env var
const
std
::
string
env_name
(
cache
.
substr
(
pos
+
1
,
after
-
pos
-
1
));
auto
env_ptr
=
std
::
getenv
(
env_name
.
c_str
());
const
std
::
string
env_value
(
env_ptr
!=
nullptr
?
env_ptr
:
""
);
cache
.
erase
(
pos
,
after
-
pos
);
cache
.
insert
(
pos
,
env_value
);
printout
(
INFO
,
"FileLoader"
,
"$"
+
env_name
+
" -> "
+
env_value
);
}
// create file path
fs
::
path
file_path
(
file
);
// create hash from url, hex of unsigned long long
std
::
string
hash
=
fmt
::
format
(
"{:016x}"
,
dd4hep
::
detail
::
hash64
(
url
));
// TODO: Use c++20 std::fmt
// create file parent path, if not exists
fs
::
path
parent_path
=
file_path
.
parent_path
();
if
(
!
fs
::
exists
(
parent_path
))
{
if
(
fs
::
create_directories
(
parent_path
)
==
false
)
{
printout
(
ERROR
,
"FileLoader"
,
"parent path "
+
parent_path
.
string
()
+
" cannot be created"
);
printout
(
ERROR
,
"FileLoader"
,
"check permissions and retry"
);
std
::
quick_exit
(
1
);
}
}
// if file exists and is symlink to correct hash
fs
::
path
hash_path
(
parent_path
/
hash
);
if
(
fs
::
exists
(
file_path
)
&&
fs
::
equivalent
(
file_path
,
hash_path
))
{
printout
(
INFO
,
"FileLoader"
,
"Link "
+
file
+
" -> hash "
+
hash
+
" already exists"
);
return
0
;
}
// if hash does not exist, we try to retrieve file from cache
if
(
!
fs
::
exists
(
hash_path
))
{
// recursive loop into cache directory
fs
::
path
cache_path
(
cache
);
printout
(
INFO
,
"FileLoader"
,
"Cache "
+
cache_path
.
string
());
if
(
fs
::
exists
(
cache_path
))
{
for
(
auto
const
&
dir_entry
:
fs
::
recursive_directory_iterator
(
cache_path
))
{
if
(
!
dir_entry
.
is_directory
())
continue
;
fs
::
path
cache_dir_path
=
cache_path
/
dir_entry
;
printout
(
INFO
,
"FileLoader"
,
"Checking "
+
cache_dir_path
.
string
());
fs
::
path
cache_hash_path
=
cache_dir_path
/
hash
;
if
(
fs
::
exists
(
cache_hash_path
))
{
// symlink hash to cache/.../hash
printout
(
INFO
,
"FileLoader"
,
"File "
+
file
+
" with hash "
+
hash
+
" found in "
+
cache_hash_path
.
string
());
try
{
fs
::
create_symlink
(
cache_hash_path
,
hash_path
);
}
catch
(
const
fs
::
filesystem_error
&
)
{
printout
(
ERROR
,
"FileLoader"
,
"unable to link from "
+
hash_path
.
string
()
+
" to "
+
cache_hash_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check permissions and retry"
);
std
::
quick_exit
(
1
);
}
break
;
}
}
}
}
// if hash does not exist, we try to retrieve file from url
if
(
!
fs
::
exists
(
hash_path
))
{
cmd
=
fmt
::
format
(
cmd
,
url
,
hash_path
.
c_str
());
// TODO: Use c++20 std::fmt
printout
(
INFO
,
"FileLoader"
,
"Downloading "
+
file
+
" as hash "
+
hash
+
" with "
+
cmd
);
// run cmd
auto
ret
=
std
::
system
(
cmd
.
c_str
());
if
(
!
fs
::
exists
(
hash_path
))
{
printout
(
ERROR
,
"FileLoader"
,
"unable to run cmd "
+
cmd
);
printout
(
ERROR
,
"FileLoader"
,
"check command and retry"
);
std
::
quick_exit
(
1
);
}
}
// check if file already exists
if
(
fs
::
exists
(
file_path
))
{
// file already exists
if
(
fs
::
is_symlink
(
file_path
))
{
// file is symlink
if
(
fs
::
equivalent
(
hash_path
,
fs
::
read_symlink
(
file_path
)))
{
// link points to correct path
return
0
;
}
else
{
// link points to incorrect path
if
(
fs
::
remove
(
file_path
)
==
false
)
{
printout
(
ERROR
,
"FileLoader"
,
"unable to remove symlink "
+
file_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check permissions or remove manually"
);
std
::
quick_exit
(
1
);
}
}
}
else
{
// file exists but not symlink
printout
(
ERROR
,
"FileLoader"
,
"will not remove actual file "
+
file_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check content, remove manually, and retry"
);
std
::
quick_exit
(
1
);
}
}
// file_path now does not exist
// symlink file_path to hash_path
try
{
// use new path from hash so file link is local
fs
::
create_symlink
(
fs
::
path
(
hash
),
file_path
);
}
catch
(
const
fs
::
filesystem_error
&
)
{
printout
(
ERROR
,
"FileLoader"
,
"unable to link from "
+
file_path
.
string
()
+
" to "
+
hash_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check permissions and retry"
);
std
::
quick_exit
(
1
);
}
EnsureFileFromURLExists
(
url
,
file
,
cache
,
cmd
);
return
0
;
}
...
...
This diff is collapsed.
Click to expand it.
src/FileLoaderHelper.h
0 → 100644
+
143
−
0
View file @
b4ea1bf0
#pragma once
#include
<DD4hep/DetFactoryHelper.h>
#include
<DD4hep/Primitives.h>
#include
<DD4hep/Factories.h>
#include
<DD4hep/Printout.h>
#include
<fmt/core.h>
#include
<filesystem>
#include
<iostream>
#include
<cstdlib>
#include
<string>
namespace
fs
=
std
::
filesystem
;
using
namespace
dd4hep
;
// Function to download files
inline
void
EnsureFileFromURLExists
(
std
::
string
url
,
std
::
string
file
,
std
::
string
cache
=
""
,
std
::
string
cmd
=
"curl --retry 5 -f {0} -o {1}"
)
{
// parse cache for environment variables
auto
pos
=
std
::
string
::
npos
;
while
((
pos
=
cache
.
find
(
'$'
))
!=
std
::
string
::
npos
)
{
auto
after
=
cache
.
find_first_not_of
(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"_"
,
pos
+
1
);
if
(
after
==
std
::
string
::
npos
)
after
=
cache
.
size
();
// cache ends on env var
const
std
::
string
env_name
(
cache
.
substr
(
pos
+
1
,
after
-
pos
-
1
));
auto
env_ptr
=
std
::
getenv
(
env_name
.
c_str
());
const
std
::
string
env_value
(
env_ptr
!=
nullptr
?
env_ptr
:
""
);
cache
.
erase
(
pos
,
after
-
pos
);
cache
.
insert
(
pos
,
env_value
);
printout
(
INFO
,
"FileLoader"
,
"$"
+
env_name
+
" -> "
+
env_value
);
}
// create file path
fs
::
path
file_path
(
file
);
// create hash from url, hex of unsigned long long
std
::
string
hash
=
fmt
::
format
(
"{:016x}"
,
dd4hep
::
detail
::
hash64
(
url
));
// TODO: Use c++20 std::fmt
// create file parent path, if not exists
fs
::
path
parent_path
=
file_path
.
parent_path
();
if
(
!
fs
::
exists
(
parent_path
))
{
if
(
fs
::
create_directories
(
parent_path
)
==
false
)
{
printout
(
ERROR
,
"FileLoader"
,
"parent path "
+
parent_path
.
string
()
+
" cannot be created"
);
printout
(
ERROR
,
"FileLoader"
,
"check permissions and retry"
);
std
::
quick_exit
(
1
);
}
}
// if file exists and is symlink to correct hash
fs
::
path
hash_path
(
parent_path
/
hash
);
if
(
fs
::
exists
(
file_path
)
&&
fs
::
equivalent
(
file_path
,
hash_path
))
{
printout
(
INFO
,
"FileLoader"
,
"Link "
+
file
+
" -> hash "
+
hash
+
" already exists"
);
return
;
}
// if hash does not exist, we try to retrieve file from cache
if
(
!
fs
::
exists
(
hash_path
))
{
// recursive loop into cache directory
fs
::
path
cache_path
(
cache
);
printout
(
INFO
,
"FileLoader"
,
"Cache "
+
cache_path
.
string
());
if
(
fs
::
exists
(
cache_path
))
{
for
(
auto
const
&
dir_entry
:
fs
::
recursive_directory_iterator
(
cache_path
))
{
if
(
!
dir_entry
.
is_directory
())
continue
;
fs
::
path
cache_dir_path
=
cache_path
/
dir_entry
;
printout
(
INFO
,
"FileLoader"
,
"Checking "
+
cache_dir_path
.
string
());
fs
::
path
cache_hash_path
=
cache_dir_path
/
hash
;
if
(
fs
::
exists
(
cache_hash_path
))
{
// symlink hash to cache/.../hash
printout
(
INFO
,
"FileLoader"
,
"File "
+
file
+
" with hash "
+
hash
+
" found in "
+
cache_hash_path
.
string
());
try
{
fs
::
create_symlink
(
cache_hash_path
,
hash_path
);
}
catch
(
const
fs
::
filesystem_error
&
)
{
printout
(
ERROR
,
"FileLoader"
,
"unable to link from "
+
hash_path
.
string
()
+
" to "
+
cache_hash_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check permissions and retry"
);
std
::
quick_exit
(
1
);
}
break
;
}
}
}
}
// if hash does not exist, we try to retrieve file from url
if
(
!
fs
::
exists
(
hash_path
))
{
cmd
=
fmt
::
format
(
cmd
,
url
,
hash_path
.
c_str
());
// TODO: Use c++20 std::fmt
printout
(
INFO
,
"FileLoader"
,
"Downloading "
+
file
+
" as hash "
+
hash
+
" with "
+
cmd
);
// run cmd
auto
ret
=
std
::
system
(
cmd
.
c_str
());
if
(
!
fs
::
exists
(
hash_path
))
{
printout
(
ERROR
,
"FileLoader"
,
"unable to run cmd "
+
cmd
);
printout
(
ERROR
,
"FileLoader"
,
"check command and retry"
);
std
::
quick_exit
(
1
);
}
}
// check if file already exists
if
(
fs
::
exists
(
file_path
))
{
// file already exists
if
(
fs
::
is_symlink
(
file_path
))
{
// file is symlink
if
(
fs
::
equivalent
(
hash_path
,
fs
::
read_symlink
(
file_path
)))
{
// link points to correct path
return
;
}
else
{
// link points to incorrect path
if
(
fs
::
remove
(
file_path
)
==
false
)
{
printout
(
ERROR
,
"FileLoader"
,
"unable to remove symlink "
+
file_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check permissions or remove manually"
);
std
::
quick_exit
(
1
);
}
}
}
else
{
// file exists but not symlink
printout
(
ERROR
,
"FileLoader"
,
"will not remove actual file "
+
file_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check content, remove manually, and retry"
);
std
::
quick_exit
(
1
);
}
}
// file_path now does not exist
// symlink file_path to hash_path
try
{
// use new path from hash so file link is local
fs
::
create_symlink
(
fs
::
path
(
hash
),
file_path
);
}
catch
(
const
fs
::
filesystem_error
&
)
{
printout
(
ERROR
,
"FileLoader"
,
"unable to link from "
+
file_path
.
string
()
+
" to "
+
hash_path
.
string
());
printout
(
ERROR
,
"FileLoader"
,
"check permissions and retry"
);
std
::
quick_exit
(
1
);
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment