Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Gaudi
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
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
Gaudi
Gaudi
Commits
50442d35
Commit
50442d35
authored
6 years ago
by
Christopher Rob Jones
Browse files
Options
Downloads
Patches
Plain Diff
Use UNLIKELY
parent
5411b785
No related branches found
Branches containing commit
No related tags found
Tags containing commit
1 merge request
!817
GaudiAlg : Minor changes to histogram summary printout to support QM tests
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
GaudiUtils/src/Lib/HistoStats.cpp
+44
-53
44 additions, 53 deletions
GaudiUtils/src/Lib/HistoStats.cpp
with
44 additions
and
53 deletions
GaudiUtils/src/Lib/HistoStats.cpp
+
44
−
53
View file @
50442d35
...
@@ -32,9 +32,9 @@ namespace
...
@@ -32,9 +32,9 @@ namespace
{
{
// ==========================================================================
// ==========================================================================
/// define local "bad" value
/// define local "bad" value
const
double
s_bad
=
std
::
numeric_limits
<
float
>::
lowest
();
const
constexpr
double
s_bad
=
std
::
numeric_limits
<
float
>::
lowest
();
/// define local "bad" value
/// define local "bad" value
const
long
s_long_bad
=
std
::
numeric_limits
<
int
>::
min
();
const
constexpr
long
s_long_bad
=
std
::
numeric_limits
<
int
>::
min
();
// ==========================================================================
// ==========================================================================
// implementations
// implementations
// ============================================================================
// ============================================================================
...
@@ -68,7 +68,7 @@ namespace
...
@@ -68,7 +68,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_moment
(
const
HISTO
*
histo
,
const
unsigned
int
order
,
const
double
value
=
0
)
double
_moment
(
const
HISTO
*
histo
,
const
unsigned
int
order
,
const
double
value
=
0
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
if
(
0
==
order
)
{
if
(
0
==
order
)
{
...
@@ -96,8 +96,8 @@ namespace
...
@@ -96,8 +96,8 @@ namespace
const
auto
lE
=
axis
.
binLowerEdge
(
i
);
const
auto
lE
=
axis
.
binLowerEdge
(
i
);
const
auto
uE
=
axis
.
binUpperEdge
(
i
);
const
auto
uE
=
axis
.
binUpperEdge
(
i
);
//
//
const
auto
yBin
=
histo
->
binHeight
(
i
);
// bin weight
const
auto
yBin
=
histo
->
binHeight
(
i
);
// bin weight
const
double
xBin
=
0.5
*
(
lE
+
uE
);
// bin center
const
auto
xBin
=
0.5
*
double
(
lE
+
uE
);
// bin center
//
//
weight
+=
yBin
;
weight
+=
yBin
;
result
+=
yBin
*
std
::
pow
(
xBin
-
value
,
order
);
result
+=
yBin
*
std
::
pow
(
xBin
-
value
,
order
);
...
@@ -113,7 +113,7 @@ namespace
...
@@ -113,7 +113,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_momentErr
(
const
HISTO
*
histo
,
const
unsigned
int
order
)
double
_momentErr
(
const
HISTO
*
histo
,
const
unsigned
int
order
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
n
=
_nEff
(
histo
);
const
auto
n
=
_nEff
(
histo
);
...
@@ -131,7 +131,7 @@ namespace
...
@@ -131,7 +131,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_centralMoment
(
const
HISTO
*
histo
,
const
unsigned
int
order
)
double
_centralMoment
(
const
HISTO
*
histo
,
const
unsigned
int
order
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
if
(
0
==
order
)
{
if
(
0
==
order
)
{
...
@@ -152,7 +152,7 @@ namespace
...
@@ -152,7 +152,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_centralMomentErr
(
const
HISTO
*
histo
,
const
unsigned
int
order
)
double
_centralMomentErr
(
const
HISTO
*
histo
,
const
unsigned
int
order
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
n
=
_nEff
(
histo
);
const
auto
n
=
_nEff
(
histo
);
...
@@ -174,7 +174,7 @@ namespace
...
@@ -174,7 +174,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_skewness
(
const
HISTO
*
histo
)
double
_skewness
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
mu3
=
_centralMoment
(
histo
,
3
);
const
auto
mu3
=
_centralMoment
(
histo
,
3
);
...
@@ -187,7 +187,7 @@ namespace
...
@@ -187,7 +187,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_skewnessErr
(
const
HISTO
*
histo
)
double
_skewnessErr
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
n
=
_nEff
(
histo
);
const
auto
n
=
_nEff
(
histo
);
...
@@ -203,7 +203,7 @@ namespace
...
@@ -203,7 +203,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_kurtosis
(
const
HISTO
*
histo
)
double
_kurtosis
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
mu4
=
_centralMoment
(
histo
,
4
);
const
auto
mu4
=
_centralMoment
(
histo
,
4
);
...
@@ -216,7 +216,7 @@ namespace
...
@@ -216,7 +216,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_kurtosisErr
(
const
HISTO
*
histo
)
double
_kurtosisErr
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
n
=
_nEff
(
histo
);
const
auto
n
=
_nEff
(
histo
);
...
@@ -235,7 +235,7 @@ namespace
...
@@ -235,7 +235,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_meanErr
(
const
HISTO
*
histo
)
double
_meanErr
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
}
const
auto
n
=
_nEff
(
histo
);
const
auto
n
=
_nEff
(
histo
);
...
@@ -247,7 +247,7 @@ namespace
...
@@ -247,7 +247,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_rmsErr
(
const
HISTO
*
histo
)
double
_rmsErr
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
}
const
auto
n
=
_nEff
(
histo
);
const
auto
n
=
_nEff
(
histo
);
...
@@ -265,7 +265,7 @@ namespace
...
@@ -265,7 +265,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_sumBinHeightErr
(
const
HISTO
*
histo
)
double
_sumBinHeightErr
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
}
//
//
...
@@ -287,7 +287,7 @@ namespace
...
@@ -287,7 +287,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_sumAllBinHeightErr
(
const
HISTO
*
histo
)
double
_sumAllBinHeightErr
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
}
//
//
...
@@ -307,7 +307,7 @@ namespace
...
@@ -307,7 +307,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_overflowEntriesFrac
(
const
HISTO
*
histo
)
double
_overflowEntriesFrac
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
overflow
=
histo
->
binEntries
(
AIDA
::
IAxis
::
OVERFLOW_BIN
);
const
auto
overflow
=
histo
->
binEntries
(
AIDA
::
IAxis
::
OVERFLOW_BIN
);
...
@@ -330,7 +330,7 @@ namespace
...
@@ -330,7 +330,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_underflowEntriesFrac
(
const
HISTO
*
histo
)
double
_underflowEntriesFrac
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
underflow
=
histo
->
binEntries
(
AIDA
::
IAxis
::
UNDERFLOW_BIN
);
const
auto
underflow
=
histo
->
binEntries
(
AIDA
::
IAxis
::
UNDERFLOW_BIN
);
...
@@ -353,7 +353,7 @@ namespace
...
@@ -353,7 +353,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_overflowIntegralFrac
(
const
HISTO
*
histo
)
double
_overflowIntegralFrac
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
overflow
=
histo
->
binHeight
(
AIDA
::
IAxis
::
OVERFLOW_BIN
);
const
auto
overflow
=
histo
->
binHeight
(
AIDA
::
IAxis
::
OVERFLOW_BIN
);
...
@@ -373,7 +373,7 @@ namespace
...
@@ -373,7 +373,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_underflowIntegralFrac
(
const
HISTO
*
histo
)
double
_underflowIntegralFrac
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
underflow
=
histo
->
binHeight
(
AIDA
::
IAxis
::
UNDERFLOW_BIN
);
const
auto
underflow
=
histo
->
binHeight
(
AIDA
::
IAxis
::
UNDERFLOW_BIN
);
...
@@ -393,7 +393,7 @@ namespace
...
@@ -393,7 +393,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_overflowEntriesFracErr
(
const
HISTO
*
histo
)
double
_overflowEntriesFracErr
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
...
@@ -416,7 +416,7 @@ namespace
...
@@ -416,7 +416,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_underflowEntriesFracErr
(
const
HISTO
*
histo
)
double
_underflowEntriesFracErr
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
...
@@ -439,7 +439,7 @@ namespace
...
@@ -439,7 +439,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_overflowIntegralFracErr
(
const
HISTO
*
histo
)
double
_overflowIntegralFracErr
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
...
@@ -457,7 +457,7 @@ namespace
...
@@ -457,7 +457,7 @@ namespace
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
double
error2
=
std
::
pow
(
(
double
)
oErr
,
2
);
auto
error2
=
std
::
pow
(
(
double
)
oErr
,
2
);
error2
+=
(
std
::
pow
(
(
double
)
aErr
,
2
)
*
std
::
pow
(
(
double
)
overflow
,
2
)
/
std
::
pow
(
(
double
)
all
,
2
)
);
error2
+=
(
std
::
pow
(
(
double
)
aErr
,
2
)
*
std
::
pow
(
(
double
)
overflow
,
2
)
/
std
::
pow
(
(
double
)
all
,
2
)
);
error2
/=
std
::
pow
(
(
double
)
all
,
2
);
error2
/=
std
::
pow
(
(
double
)
all
,
2
);
//
//
...
@@ -469,7 +469,7 @@ namespace
...
@@ -469,7 +469,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_underflowIntegralFracErr
(
const
HISTO
*
histo
)
double
_underflowIntegralFracErr
(
const
HISTO
*
histo
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
...
@@ -487,7 +487,7 @@ namespace
...
@@ -487,7 +487,7 @@ namespace
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
double
error2
=
std
::
pow
(
(
double
)
oErr
,
2
);
auto
error2
=
std
::
pow
(
(
double
)
oErr
,
2
);
error2
+=
(
std
::
pow
(
(
double
)
aErr
,
2
)
*
std
::
pow
(
(
double
)
underflow
,
2
)
/
std
::
pow
(
(
double
)
all
,
2
)
);
error2
+=
(
std
::
pow
(
(
double
)
aErr
,
2
)
*
std
::
pow
(
(
double
)
underflow
,
2
)
/
std
::
pow
(
(
double
)
all
,
2
)
);
error2
/=
std
::
pow
(
(
double
)
all
,
2
);
error2
/=
std
::
pow
(
(
double
)
all
,
2
);
//
//
...
@@ -499,7 +499,7 @@ namespace
...
@@ -499,7 +499,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
long
_nEntries
(
const
HISTO
*
histo
,
const
int
imax
)
long
_nEntries
(
const
HISTO
*
histo
,
const
int
imax
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_long_bad
;
return
s_long_bad
;
}
// RETURN
}
// RETURN
if
(
0
>
imax
)
{
if
(
0
>
imax
)
{
...
@@ -511,11 +511,9 @@ namespace
...
@@ -511,11 +511,9 @@ namespace
const
auto
&
axis
=
histo
->
axis
();
const
auto
&
axis
=
histo
->
axis
();
// number of bins
// number of bins
const
auto
nBins
=
axis
.
bins
();
const
auto
nBins
=
axis
.
bins
();
// loop over all bins
// loop over bins
for
(
int
i
=
0
;
i
<
nBins
;
++
i
)
{
for
(
int
i
=
0
;
i
<
nBins
&&
i
<
imax
;
++
i
)
{
if
(
i
<
imax
)
{
result
+=
histo
->
binEntries
(
i
);
result
+=
histo
->
binEntries
(
i
);
}
}
}
//
//
if
(
nBins
<
imax
)
{
if
(
nBins
<
imax
)
{
...
@@ -532,7 +530,7 @@ namespace
...
@@ -532,7 +530,7 @@ namespace
const
int
imin
,
// minimal bin number (included)
const
int
imin
,
// minimal bin number (included)
const
int
imax
)
// maximal bin number (not included)
const
int
imax
)
// maximal bin number (not included)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_long_bad
;
return
s_long_bad
;
}
// RETURN
}
// RETURN
if
(
imin
==
imax
)
{
if
(
imin
==
imax
)
{
...
@@ -553,11 +551,9 @@ namespace
...
@@ -553,11 +551,9 @@ namespace
if
(
nBins
<
imin
)
{
if
(
nBins
<
imin
)
{
return
0
;
return
0
;
}
// RETURN
}
// RETURN
// loop over all bins
// loop over bins
for
(
int
i
=
0
;
i
<
nBins
;
++
i
)
{
for
(
int
i
=
imin
;
i
<
nBins
&&
imin
<=
i
&&
i
<
imax
;
++
i
)
{
if
(
imin
<=
i
&&
i
<
imax
)
{
result
+=
histo
->
binEntries
(
i
);
result
+=
histo
->
binEntries
(
i
);
}
}
}
//
//
if
(
nBins
<
imax
)
{
if
(
nBins
<
imax
)
{
...
@@ -567,12 +563,12 @@ namespace
...
@@ -567,12 +563,12 @@ namespace
return
result
;
// RETURN
return
result
;
// RETURN
}
}
// ============================================================================
// ============================================================================
// get the fraction of entries in histogram up to the
certain
// get the fraction of entries in histogram up to the
given bin (not-included)
// ============================================================================
// ============================================================================
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_nEntriesFrac
(
const
HISTO
*
histo
,
const
int
imax
)
double
_nEntriesFrac
(
const
HISTO
*
histo
,
const
int
imax
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
...
@@ -592,19 +588,14 @@ namespace
...
@@ -592,19 +588,14 @@ namespace
}
}
// ============================================================================
// ============================================================================
/* get fraction of entries in histogram form the certain
/* get fraction of entries in histogram form the certain
* minimal bin up to the certain maximal bin (not-included)
* minimal bin up to the certain maximal bin (not-included) */
* @param histo the pointer to the histogram
* @param imin the minimal bin number (included)
* @param imax the maximal bin number (not included)
* @param fraction of entries
*/
// ============================================================================
// ============================================================================
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_nEntriesFrac
(
const
HISTO
*
histo
,
double
_nEntriesFrac
(
const
HISTO
*
histo
,
const
int
imin
,
// minimal bin number (included)
const
int
imin
,
// minimal bin number (included)
const
int
imax
)
// maximal bin number (not included)
const
int
imax
)
// maximal bin number (not included)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
const
auto
N
=
histo
->
allEntries
();
const
auto
N
=
histo
->
allEntries
();
...
@@ -627,7 +618,7 @@ namespace
...
@@ -627,7 +618,7 @@ namespace
template
<
typename
HISTO
>
template
<
typename
HISTO
>
double
_nEntriesFracErr
(
const
HISTO
*
histo
,
const
int
imax
)
double
_nEntriesFracErr
(
const
HISTO
*
histo
,
const
int
imax
)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
...
@@ -643,8 +634,8 @@ namespace
...
@@ -643,8 +634,8 @@ namespace
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
const
double
_n1
=
std
::
max
(
(
double
)
n
,
1.0
);
const
auto
_n1
=
std
::
max
(
(
double
)
n
,
1.0
);
const
double
_n2
=
std
::
max
(
(
double
)(
N
-
n
),
1.0
);
const
auto
_n2
=
std
::
max
(
(
double
)(
N
-
n
),
1.0
);
//
//
return
std
::
sqrt
(
_n1
*
(
_n2
/
N
)
)
/
N
;
// RETURN
return
std
::
sqrt
(
_n1
*
(
_n2
/
N
)
)
/
N
;
// RETURN
}
}
...
@@ -656,7 +647,7 @@ namespace
...
@@ -656,7 +647,7 @@ namespace
const
int
imin
,
// minimal bin number (included)
const
int
imin
,
// minimal bin number (included)
const
int
imax
)
// maximal bin number (not included)
const
int
imax
)
// maximal bin number (not included)
{
{
if
(
!
histo
)
{
if
(
UNLIKELY
(
!
histo
)
)
{
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
...
@@ -672,8 +663,8 @@ namespace
...
@@ -672,8 +663,8 @@ namespace
return
s_bad
;
return
s_bad
;
}
// RETURN
}
// RETURN
//
//
const
double
_n1
=
std
::
max
(
(
double
)
n
,
1.0
);
const
auto
_n1
=
std
::
max
(
(
double
)
n
,
1.0
);
const
double
_n2
=
std
::
max
(
(
double
)(
N
-
n
),
1.0
);
const
auto
_n2
=
std
::
max
(
(
double
)(
N
-
n
),
1.0
);
//
//
return
std
::
sqrt
(
_n1
*
(
_n2
/
N
)
)
/
N
;
// RETURN
return
std
::
sqrt
(
_n1
*
(
_n2
/
N
)
)
/
N
;
// RETURN
}
}
...
...
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