Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ATLAS-EGamma
athena
Commits
03378f4b
Commit
03378f4b
authored
Jun 30, 2022
by
Shaun Roe
Committed by
Adam Edward Barton
Jun 30, 2022
Browse files
23.0-cppcheck-dqm_algorithms
23.0-cppcheck-dqm_algorithms
parent
6443f35b
Changes
17
Hide whitespace changes
Inline
Side-by-side
DataQuality/dqm_algorithms/src/BinsDiffByStrips.cxx
View file @
03378f4b
...
...
@@ -768,7 +768,7 @@ if(name_flag==1){
double
maxvalue
=
0
;
int
counter
=
0
;
int
counter2
=
0
;
for
(
vector
<
tools
::
binContainer
>::
const_iterator
it
=
AllBinInOneStrip
.
begin
();
it
!=
AllBinInOneStrip
.
end
();
it
++
){
for
(
vector
<
tools
::
binContainer
>::
const_iterator
it
=
AllBinInOneStrip
.
begin
();
it
!=
AllBinInOneStrip
.
end
();
++
it
){
int
flag_my
=
i
==
0
||
(
bin_entries_status
[
counter
]
&&
it
->
value
<=
maxvalue_pre
);
if
(
fabs
(
it
->
value
)
>=
fabs
(
maxvalue
)
&&
flag_my
)
{
maxvalue
=
it
->
value
;
...
...
DataQuality/dqm_algorithms/src/Chi2Test_2D.cxx
View file @
03378f4b
...
...
@@ -206,7 +206,7 @@ catch( dqm_core::Exception & ex ) {
p
=
ChisqValues
.
end
();
//since the iterator points to one past the end, must decrement before we use it.
p
--
;
--
p
;
//define a second iterator for the map, do not decrement it, as it will be assigned to a point in the map before use
map
<
double
,
int
>::
iterator
p2
;
...
...
@@ -270,7 +270,7 @@ while(mymap.size()>0)
if
(
p
==
ChisqValues
.
begin
()
||
k
>
Num_to_print
)
{
break
;}
p
--
;
--
p
;
k
++
;
}
...
...
DataQuality/dqm_algorithms/src/MDTCluster.cxx
View file @
03378f4b
...
...
@@ -93,13 +93,13 @@ MDTCluster::execute( const std::string& name, const TObject& object, const dqm_c
ref
=
static_cast
<
TH1
*>
(
config
.
getReference
()
);
}
catch
(
dqm_core
::
Exception
&
ex
)
{
throw
dqm_core
::
BadRefHist
(
ERS_HERE
,
name
,
" Could not retr
e
ive reference"
);
throw
dqm_core
::
BadRefHist
(
ERS_HERE
,
name
,
" Could not retri
e
ve reference"
);
}
if
(
hist
->
GetDimension
()
!=
ref
->
GetDimension
()
)
{
throw
dqm_core
::
BadRefHist
(
ERS_HERE
,
name
,
"Reference VS histo: Different dimension!"
);
}
if
(
hist
->
GetNbinsX
()
!=
ref
->
GetNbinsX
()
)
{
throw
dqm_core
::
BadRefHist
(
ERS_HERE
,
name
,
"Reference VS histo: Different bin numb
r
e in X axis!"
);
throw
dqm_core
::
BadRefHist
(
ERS_HERE
,
name
,
"Reference VS histo: Different bin numbe
r
in X axis!"
);
}
//Check of statistics
...
...
@@ -156,48 +156,41 @@ MDTCluster::execute( const std::string& name, const TObject& object, const dqm_c
//and finishes when the difference is smaller.
i
=
0
;
bool
cluster_open
=
0
;
bool
cluster_open
=
false
;
std
::
pair
<
int
,
int
>
bin_start_end
;
std
::
pair
<
int
,
std
::
pair
<
int
,
int
>
>
cluster_size_binStart_binEnd
;
std
::
vector
<
std
::
pair
<
int
,
std
::
pair
<
int
,
int
>
>
>
clusters
;
int
size
=
0
;
for
(
i
=
0
;
i
<
diff
.
size
();
i
++
){
if
(
fabs
(
diff
[
i
])
>
n_sigma
*
sqrt
(
hist
->
GetBinContent
(
i
+
1
)
+
ref
->
GetBinContent
(
i
+
1
)
*
norm
)){
if
(
cluster_open
){
if
(
i
!=
0
){
if
(
diff
[
i
-
1
]
*
diff
[
i
]
>
0
){
size
++
;
};
if
(
diff
[
i
-
1
]
*
diff
[
i
]
<=
0
){
}
else
{
//diff[i-1]*diff[i]<=0
if
(
size
>=
cluster_size
){
bin_start_end
.
second
=
i
;
cluster_size_binStart_binEnd
.
first
=
size
;
cluster_size_binStart_binEnd
.
second
=
bin_start_end
;
clusters
.
push_back
(
cluster_size_binStart_binEnd
);
};
cluster_open
=
0
;
};
cluster_open
=
false
;
};
if
(
i
==
0
){
}
else
{
//i ===0
ERS_INFO
(
"Cluster searching fail"
);
dqm_core
::
Result
*
result
=
new
dqm_core
::
Result
(
dqm_core
::
Result
::
Undefined
);
result
->
tags_
[
"i"
]
=
i
;
return
result
;
};
};
};
};
if
(
!
cluster_open
){
cluster_open
=
1
;
cluster_open
=
true
;
size
=
0
;
bin_start_end
.
first
=
i
+
1
;
size
++
;
};
};
if
(
fabs
(
diff
[
i
])
<=
n_sigma
*
sqrt
(
hist
->
GetBinContent
(
i
+
1
)
+
ref
->
GetBinContent
(
i
+
1
)
*
norm
)){
...
...
@@ -208,7 +201,7 @@ MDTCluster::execute( const std::string& name, const TObject& object, const dqm_c
cluster_size_binStart_binEnd
.
second
=
bin_start_end
;
clusters
.
push_back
(
cluster_size_binStart_binEnd
);
};
cluster_open
=
0
;
cluster_open
=
false
;
};
};
if
(
i
==
diff
.
size
()
-
1
){
...
...
@@ -219,7 +212,7 @@ MDTCluster::execute( const std::string& name, const TObject& object, const dqm_c
cluster_size_binStart_binEnd
.
second
=
bin_start_end
;
clusters
.
push_back
(
cluster_size_binStart_binEnd
);
};
cluster_open
=
0
;
cluster_open
=
false
;
};
};
};
...
...
DataQuality/dqm_algorithms/src/MDTMLOverview.cxx
View file @
03378f4b
...
...
@@ -95,7 +95,7 @@ MDTMLOverview::execute( const std::string& name, const TObject& object, const dq
ref
=
static_cast
<
TH1
*>
(
config
.
getReference
()
);
}
catch
(
dqm_core
::
Exception
&
ex
)
{
throw
dqm_core
::
BadRefHist
(
ERS_HERE
,
name
,
" Could not retr
e
ive reference"
);
throw
dqm_core
::
BadRefHist
(
ERS_HERE
,
name
,
" Could not retri
e
ve reference"
);
}
if
(
hist
->
GetDimension
()
!=
ref
->
GetDimension
()
)
{
...
...
@@ -120,8 +120,9 @@ MDTMLOverview::execute( const std::string& name, const TObject& object, const dq
int
binX
=
hist
->
GetNbinsX
();
//double x_center=0;
std
::
list
<
int
>
hist_buffer
;
std
::
list
<
int
>
ref_buffer
;
std
::
vector
<
int
>
hist_buffer
;
std
::
vector
<
int
>
ref_buffer
;
std
::
vector
<
double
>
new_empty_bins
;
int
count
=
0
;
...
...
@@ -131,32 +132,30 @@ MDTMLOverview::execute( const std::string& name, const TObject& object, const dq
if
(
ref
->
GetBinContent
(
x_index
)
!=
0
)
ref_buffer
.
push_back
((
int
)
ref
->
GetBinContent
(
x_index
));
}
};
hist_buffer
.
sort
();
std
::
list
<
int
>::
iterator
it_hist
;
int
size_hist
=
hist_buffer
.
size
();
it_hist
=
hist_buffer
.
begin
();
for
(
int
i
=
1
;
i
<
(
size_hist
/
2
);
i
++
)
it_hist
++
;
int
mediana_hist
=
*
it_hist
;
if
(
ref_y_n
==
1
)
{
ref_buffer
.
sort
();
std
::
list
<
int
>::
iterator
it_ref
;
int
size_ref
=
ref_buffer
.
size
();
it_ref
=
ref_buffer
.
begin
();
for
(
int
j
=
1
;
j
<
(
size_ref
/
2
);
j
++
)
it_ref
++
;
int
mediana_ref
=
*
it_ref
;
auto
median
=
[](
std
::
vector
<
int
>
&
v
)
->
int
{
const
auto
midPoint
=
v
.
begin
()
+
v
.
size
()
/
2
;
std
::
nth_element
(
v
.
begin
(),
midPoint
,
v
.
end
());
return
v
[
v
.
size
()
/
2
];
};
double
percentThreshold
=
thresh
*
0.01
;
const
int
mediana_hist
=
median
(
hist_buffer
);
if
(
ref_y_n
==
1
)
{
const
int
mediana_ref
=
median
(
ref_buffer
);
for
(
int
xi
=
1
;
xi
<=
binX
;
xi
++
){
if
(
hist
->
GetBinContent
(
xi
)
<
mediana_hist
*
t
hresh
/
100
&&
ref
->
GetBinContent
(
xi
)
>=
mediana_ref
*
t
hresh
/
100
){
if
(
hist
->
GetBinContent
(
xi
)
<
mediana_hist
*
percentT
hresh
old
&&
ref
->
GetBinContent
(
xi
)
>=
mediana_ref
*
percentT
hresh
old
){
count
++
;
new_empty_bins
.
push_back
(
hist
->
GetBinCenter
(
xi
));
};
};
}
else
if
(
ref_y_n
==
0
){
for
(
int
xi
=
1
;
xi
<=
binX
;
xi
++
){
if
(
hist
->
GetBinContent
(
xi
)
<
mediana_hist
*
t
hresh
/
100
){
if
(
hist
->
GetBinContent
(
xi
)
<
mediana_hist
*
percentT
hresh
old
){
count
++
;
new_empty_bins
.
push_back
(
hist
->
GetBinCenter
(
xi
));
};
...
...
DataQuality/dqm_algorithms/src/MDTOverview.cxx
View file @
03378f4b
...
...
@@ -121,8 +121,8 @@ MDTOverview::execute( const std::string& name, const TObject& object, const dqm_
int
binY
=
hist
->
GetNbinsY
();
double
nML
=
0
;
std
::
list
<
int
>
hist_buffer
;
std
::
list
<
int
>
ref_buffer
;
std
::
vector
<
int
>
hist_buffer
;
std
::
vector
<
int
>
ref_buffer
;
for
(
int
x_index
=
1
;
x_index
<=
binX
;
x_index
++
){
for
(
int
y_index
=
1
;
y_index
<=
binY
;
y_index
++
){
...
...
@@ -183,23 +183,17 @@ MDTOverview::execute( const std::string& name, const TObject& object, const dqm_
}
}
hist_buffer
.
sort
();
ref_buffer
.
sort
();
std
::
list
<
int
>::
iterator
it_hist
;
std
::
list
<
int
>::
iterator
it_ref
;
int
size_hist
=
hist_buffer
.
size
();
int
size_ref
=
ref_buffer
.
size
();
it_hist
=
hist_buffer
.
begin
();
it_ref
=
ref_buffer
.
begin
();
auto
median
=
[](
std
::
vector
<
int
>
&
v
)
->
int
{
const
auto
midPoint
=
v
.
begin
()
+
v
.
size
()
/
2
;
std
::
nth_element
(
v
.
begin
(),
midPoint
,
v
.
end
());
return
v
[
v
.
size
()
/
2
];
};
for
(
int
i
=
1
;
i
<
(
size_hist
/
2
);
i
++
)
it_hist
++
;
for
(
int
i
=
1
;
i
<
(
size_ref
/
2
);
i
++
)
it_ref
++
;
int
mediana_hist
=
*
it_hist
;
int
mediana_ref
=
*
it_ref
;
int
mediana_hist
=
median
(
hist_buffer
);
int
mediana_ref
=
median
(
ref_buffer
);
const
int
size_hist
=
hist_buffer
.
size
();
int
count
=
0
;
int
count_non_0
=
0
;
...
...
DataQuality/dqm_algorithms/summary/DivideByHist.cxx
View file @
03378f4b
...
...
@@ -157,7 +157,7 @@ dqm_algorithms::summary::DivideByHist::execute( const std::string & name,
}
//end loop over parameters map
//Now loop over the paramVecMap to finish the algConfig
for
(
std
::
map
<
std
::
string
,
double
>::
const_iterator
pvIter
=
paramVecMap
.
begin
();
pvIter
!=
paramVecMap
.
end
();
pvIter
++
){
for
(
std
::
map
<
std
::
string
,
double
>::
const_iterator
pvIter
=
paramVecMap
.
begin
();
pvIter
!=
paramVecMap
.
end
();
++
pvIter
){
algConfig
.
addParameter
(
pvIter
->
first
,
pvIter
->
second
);
}
...
...
DataQuality/dqm_algorithms/summary/JetWorstCaseSummary.cxx
View file @
03378f4b
...
...
@@ -41,7 +41,7 @@ dqm_algorithms::summary::JetWorstCaseSummary::execute( const std::string & ,
unsigned
int
undefined
=
0
;
unsigned
int
skipped
=
0
;
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
iter
++
){
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
++
iter
){
//If weight is 0 skip this result. Allow to "turn off"
// results in summary makers
...
...
DataQuality/dqm_algorithms/summary/MDTWorstCaseSummary.cxx
View file @
03378f4b
...
...
@@ -42,7 +42,7 @@ dqm_algorithms::summary::MDTWorstCaseSummary::execute( const std::string & ,
double
TotalBins
=
0
;
int
NBins
=
0
;
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
iter
++
){
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
++
iter
){
std
::
string
name
=
(
*
iter
).
first
;
if
(
name
.
find
(
"NumberOfHitsIn"
)
==
std
::
string
::
npos
)
continue
;
...
...
DataQuality/dqm_algorithms/summary/PercentSummary.cxx
View file @
03378f4b
...
...
@@ -56,7 +56,7 @@ dqm_algorithms::summary::PercentSummary::execute( const std::string & ,
dqm_core
::
Result
*
newresult
=
new
dqm_core
::
Result
();
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
iter
++
){
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
++
iter
){
dqm_core
::
Result
::
Status
status
=
iter
->
second
->
getResult
().
get
()
->
status_
;
if
(
status
==
dqm_core
::
Result
::
Red
)
{
rweight
+=
iter
->
second
->
getWeight
();
...
...
DataQuality/dqm_algorithms/summary/SimpleSummary.cxx
View file @
03378f4b
...
...
@@ -44,7 +44,7 @@ dqm_algorithms::summary::SimpleSummary::execute( const std::string & ,
float
ngrey
=
0
;
float
nblack
=
0
;
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
iter
++
){
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
++
iter
){
dqm_core
::
Result
::
Status
status
=
iter
->
second
->
getResult
().
get
()
->
status_
;
...
...
DataQuality/dqm_algorithms/summary/WorstCaseSummary.cxx
View file @
03378f4b
...
...
@@ -40,7 +40,7 @@ dqm_algorithms::summary::WorstCaseSummary::execute( const std::string & ,
unsigned
int
undefined
=
0
;
unsigned
int
skipped
=
0
;
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
iter
++
){
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
++
iter
){
//If weight is 0 skip this result. Allow to "turn off"
// results in summary makers
if
(
iter
->
second
->
getWeight
()
==
0
)
...
...
DataQuality/dqm_algorithms/summary/WorstCaseYellow.cxx
View file @
03378f4b
...
...
@@ -40,7 +40,7 @@ dqm_algorithms::summary::WorstCaseYellow::execute( const std::string & ,
unsigned
int
undefined
=
0
;
unsigned
int
skipped
=
0
;
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
iter
++
){
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
++
iter
){
//If weight is 0 skip this result. Allow to "turn off"
// results in summary makers
if
(
iter
->
second
->
getWeight
()
==
0
)
...
...
DataQuality/dqm_algorithms/summary/WorstWBlackSummary.cxx
View file @
03378f4b
...
...
@@ -40,7 +40,7 @@ dqm_algorithms::summary::WorstWBlackSummary::execute( const std::string & ,
unsigned
int
undefined
=
0
;
unsigned
int
skipped
=
0
;
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
iter
++
){
for
(
iter
=
map
.
begin
();
iter
!=
map
.
end
();
++
iter
){
//If weight is 0 skip this result. Allow to "turn off"
// results in summary makers
if
(
iter
->
second
->
getWeight
()
==
0
)
...
...
DataQuality/dqm_algorithms/tools/AlgorithmHelper.cxx
View file @
03378f4b
...
...
@@ -77,7 +77,7 @@ dqm_algorithms::tools::MakeComparisons( const std::map<std::string,double> & alg
std
::
map
<
std
::
string
,
double
>::
const_iterator
g_iter
;
for
(
g_iter
=
gthreshold
.
begin
();
g_iter
!=
gthreshold
.
end
();
g_iter
++
){
for
(
g_iter
=
gthreshold
.
begin
();
g_iter
!=
gthreshold
.
end
();
++
g_iter
){
std
::
string
name
=
(
std
::
string
)
g_iter
->
first
;
std
::
string
findname
=
name
;
...
...
@@ -187,7 +187,7 @@ dqm_algorithms::tools::CompareWithErrors( const std::map<std::string,double> & a
std
::
map
<
std
::
string
,
double
>::
const_iterator
g_iter
;
for
(
g_iter
=
gthreshold
.
begin
();
g_iter
!=
gthreshold
.
end
();
g_iter
++
){
for
(
g_iter
=
gthreshold
.
begin
();
g_iter
!=
gthreshold
.
end
();
++
g_iter
){
std
::
string
name
=
(
std
::
string
)
g_iter
->
first
;
std
::
string
findname
=
name
;
...
...
@@ -969,7 +969,7 @@ dqm_algorithms::tools::findOutliersUsingErrors( std::vector<binContainer>& input
//If max(absDiff) < minDiff, this is not considered an outlier: we are done.
std
::
map
<
double
,
binContainer
*>::
iterator
outlierCandidate
=
absDiffMap
.
end
();
outlierCandidate
--
;
//<- the last element in a map is the largest.
--
outlierCandidate
;
//<- the last element in a map is the largest.
if
(
outlierCandidate
->
first
<
minDiff
)
{
return
;
}
...
...
DataQuality/dqm_algorithms/tools/DumpConfig.cxx
View file @
03378f4b
...
...
@@ -81,7 +81,7 @@ sprintf(line, "<rel name=\"%sThresholds\" num=\"%d\">\n", Name.c_str(),objsize);
m_myfile
<<
line
;
std
::
map
<
std
::
string
,
double
>::
const_iterator
iter
;
for
(
iter
=
object
.
begin
();
iter
!=
object
.
end
();
iter
++
){
for
(
iter
=
object
.
begin
();
iter
!=
object
.
end
();
++
iter
){
if
(
Name
==
"Red"
){
m_red_id
.
push_back
(
Name
+
"Thresh_"
+
ParameterName
+
"_"
+
iter
->
first
);
}
else
{
...
...
@@ -112,7 +112,7 @@ dqm_algorithms::tools::DumpConfig::DumpThresholds(){
id
=
m_red_id
;
}
for
(
iter
=
thresh
.
begin
();
iter
!=
thresh
.
end
();
iter
++
){
for
(
iter
=
thresh
.
begin
();
iter
!=
thresh
.
end
();
++
iter
){
m_myfile
<<
"<obj class=
\"
DQThreshold
\"
id=
\"
"
+
id
[
count
]
+
"
\"
>
\n
"
;
m_myfile
<<
" <attr name=
\"
Name
\"
type=
\"
string
\"
>
\"
"
+
iter
->
first
+
"
\"
</attr>
\n
"
;
sprintf
(
line
,
" <attr name=
\"
Value
\"
type=
\"
double
\"
>%4.2f</attr>
\n
</obj>
\n\n
"
,
iter
->
second
);
...
...
@@ -131,7 +131,7 @@ dqm_algorithms::tools::DumpConfig::DumpParams(){
char
pline
[
500
];
int
count
=
0
;
for
(
iter
=
m_params
.
begin
();
iter
!=
m_params
.
end
();
iter
++
){
for
(
iter
=
m_params
.
begin
();
iter
!=
m_params
.
end
();
++
iter
){
m_myfile
<<
"<obj class=
\"
DQAlgorithmParameter
\"
id=
\"
"
+
m_param_id
[
count
]
+
"
\"
>
\n
"
;
m_myfile
<<
" <attr name=
\"
Name
\"
type=
\"
string
\"
>
\"
"
+
iter
->
first
+
"
\"
</attr>
\n
"
;
sprintf
(
pline
,
" <attr name=
\"
Value
\"
type=
\"
double
\"
num=
\"
1
\"
>%4.2f</attr>
\n
</obj>
\n\n
"
,
iter
->
second
);
...
...
@@ -195,7 +195,7 @@ dqm_algorithms::tools::DumpConfig::DumpOnlineConfig(std::string filename, bool d
m_myfile
<<
paramsline
;
std
::
map
<
std
::
string
,
double
>::
const_iterator
iter
;
for
(
iter
=
m_params
.
begin
();
iter
!=
m_params
.
end
();
iter
++
){
for
(
iter
=
m_params
.
begin
();
iter
!=
m_params
.
end
();
++
iter
){
m_myfile
<<
"
\"
DQAlgorithmParameter
\"
\"
Params_"
+
m_ParameterName
+
"_"
+
iter
->
first
+
"
\"\n
"
;
m_param_id
.
push_back
(
"Params_"
+
m_ParameterName
+
"_"
+
iter
->
first
);
}
...
...
DataQuality/dqm_algorithms/workbench/TestBinsDiffByStrips.C
View file @
03378f4b
...
...
@@ -212,7 +212,7 @@ TH1 * TestBinsDiffByStrips()
redsFlaggedYellow
++
;
}
else
if
(
trueStatus
==
3
){
greensFlaggedYellow
;
greensFlaggedYellow
++
;
}
}
break
;
...
...
DataQuality/dqm_algorithms/workbench/TestLastBinThresholdAction.C
View file @
03378f4b
...
...
@@ -2,7 +2,7 @@
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
*/
void
printHistogram
(
const
TH1
*
histogam
,
std
::
string
name
)
{
void
printHistogram
(
const
TH1
*
histogam
,
const
std
::
string
&
name
)
{
std
::
cout
<<
"===========> BEGIN Histogram: "
<<
name
<<
" <============"
<<
std
::
endl
;
histogam
->
Print
(
"All"
);
std
::
cout
<<
"------------> END Histogram: "
<<
name
<<
" <--------------"
<<
std
::
endl
;
...
...
@@ -103,7 +103,7 @@ bool testTileDataCorruption(std::string name, double value, std::array<double, 3
void
printTestStatus
(
std
::
string
test
,
bool
isTestOk
)
{
void
printTestStatus
(
const
std
::
string
&
test
,
bool
isTestOk
)
{
std
::
cout
<<
"------------------------------------------------------------"
<<
std
::
endl
;
std
::
cout
<<
"TEST ["
<<
test
<<
"]:
\t
"
<<
(
isTestOk
?
"PASSED"
:
"FAILED"
)
<<
std
::
endl
;
std
::
cout
<<
"------------------------------------------------------------"
<<
std
::
endl
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment