1 |
#include <functional>
|
2 |
#include <numeric>
|
3 |
|
4 |
#include "UserCode/L1RpcTriggerAnalysis/interface/GoldenPattern.h"
|
5 |
|
6 |
#include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
|
7 |
#include "DataFormats/MuonDetId/interface/RPCDetId.h"
|
8 |
#include "DataFormats/MuonDetId/interface/CSCDetId.h"
|
9 |
#include "DataFormats/MuonDetId/interface/DTChamberId.h"
|
10 |
|
11 |
#include "UserCode/L1RpcTriggerAnalysis/interface/RPCDetIdUtil.h"
|
12 |
#include "UserCode/L1RpcTriggerAnalysis/interface/DTphDigiSpec.h"
|
13 |
#include "UserCode/L1RpcTriggerAnalysis/interface/CSCDigiSpec.h"
|
14 |
#include "UserCode/L1RpcTriggerAnalysis/interface/RPCDigiSpec.h"
|
15 |
|
16 |
void GoldenPattern::Result::runNoCheck() const {
|
17 |
|
18 |
float fract = 1;
|
19 |
for(auto mType=myResults.cbegin();mType!=myResults.cend();++mType){
|
20 |
for (auto it=mType->second.cbegin(); it!=mType->second.cend();++it) fract *= norm(mType->first,it->second);
|
21 |
}
|
22 |
|
23 |
unsigned int nTot = 0;
|
24 |
for(auto it=nMatchedPoints.cbegin();it!=nMatchedPoints.cend();++it) nTot+=it->second;
|
25 |
|
26 |
theValue*=(myResults[GoldenPattern::POSRPC].size()==nMatchedPoints[GoldenPattern::POSRPC]);
|
27 |
theValue*=(myResults[GoldenPattern::POSDT].size()==nMatchedPoints[GoldenPattern::POSDT]);
|
28 |
theValue*=(myResults[GoldenPattern::POSCSC].size()==nMatchedPoints[GoldenPattern::POSCSC]);
|
29 |
theValue = ( nTot > 4) ? pow(fract, 1./((float) nTot)) : 0.;
|
30 |
//AK theValue = ( nTot > 4) ? -log(fract) : 9999.0;
|
31 |
}
|
32 |
|
33 |
float GoldenPattern::Result::norm(GoldenPattern::PosBenCase where, float whereInDist) const {
|
34 |
float normValue = 2.*(0.5-fabs(whereInDist-0.5));
|
35 |
//normValue = 0.95*whereInDist; //AK
|
36 |
|
37 |
static const float epsilon = 1.e-9;
|
38 |
if (normValue > epsilon) ++nMatchedPoints[where];
|
39 |
else normValue = 0.05;
|
40 |
return normValue;
|
41 |
}
|
42 |
|
43 |
bool GoldenPattern::Result::operator < (const GoldenPattern::Result &o) const {
|
44 |
if ( *this && o) {
|
45 |
if (nMatchedTot() < o.nMatchedTot()) return true;
|
46 |
else if (nMatchedTot() == o.nMatchedTot() && value() < o.value()) return true;
|
47 |
else return false;
|
48 |
}
|
49 |
else if (o) {return true; }
|
50 |
else if (*this) { return false; }
|
51 |
else return false;
|
52 |
|
53 |
// return (value() < o.value() );
|
54 |
// return false;
|
55 |
}
|
56 |
|
57 |
GoldenPattern::Result::operator bool() const {
|
58 |
return (value() > 0.1); // && hasStation1 && hasStation2);
|
59 |
}
|
60 |
|
61 |
float GoldenPattern::Result::value() const {
|
62 |
run();
|
63 |
return theValue;
|
64 |
}
|
65 |
|
66 |
unsigned int GoldenPattern::Result::nMatchedTot() const {
|
67 |
run();
|
68 |
unsigned int nTot = 0;
|
69 |
for(auto it=nMatchedPoints.cbegin();it!=nMatchedPoints.cend();++it) nTot+=it->second;
|
70 |
return nTot;
|
71 |
}
|
72 |
|
73 |
|
74 |
std::ostream & operator << (std::ostream &out, const GoldenPattern::Result& o)
|
75 |
{
|
76 |
o.run();
|
77 |
|
78 |
out <<"Result: "
|
79 |
<< " value: "<<o.theValue
|
80 |
<<" (POSRPC, POSCSC, BENCSC, POSDT, BENDT)(";
|
81 |
for(auto cit=o.myResults.cbegin();cit!=o.myResults.cend();++cit){
|
82 |
out<<o.nMatchedPoints[cit->first]<<"/"<<cit->second.size()<<", ";
|
83 |
}
|
84 |
out <<"tot:"<<o.nMatchedTot()<<")";
|
85 |
|
86 |
return out;
|
87 |
}
|
88 |
//////////////////////////////////////////////////
|
89 |
//////////////////////////////////////////////////
|
90 |
void GoldenPattern::add( GoldenPattern::PosBenCase aCase, uint32_t rawId, int posOrBen, unsigned int freq){
|
91 |
PattCore[aCase][rawId][posOrBen] += freq;
|
92 |
}
|
93 |
//////////////////////////////////////////////////
|
94 |
//////////////////////////////////////////////////
|
95 |
void GoldenPattern::add(const Pattern & p) {
|
96 |
|
97 |
const Pattern::DataType & detdigi = p ;
|
98 |
for (auto is = detdigi.cbegin(); is != detdigi.cend(); ++is) {
|
99 |
uint32_t rawId = is->first;
|
100 |
DetId detId(rawId);
|
101 |
if (detId.det() != DetId::Muon)
|
102 |
std::cout << "PROBLEM: hit in unknown Det, detID: "<<detId.det()<<std::endl;
|
103 |
switch (detId.subdetId()) {
|
104 |
case MuonSubdetId::RPC: {
|
105 |
RPCDigiSpec digi(rawId, is->second);
|
106 |
PattCore[GoldenPattern::POSRPC][rawId][digi.halfStrip()]++;
|
107 |
break;
|
108 |
}
|
109 |
case MuonSubdetId::DT: {
|
110 |
DTphDigiSpec digi(rawId, is->second);
|
111 |
if (digi.bxNum() != 0 || digi.bxCnt() != 0 || digi.ts2() != 0 || digi.code()<4) break;
|
112 |
PattCore[GoldenPattern::POSDT][rawId][digi.phi()]++;
|
113 |
PattCore[GoldenPattern::BENDT][rawId][digi.phiB()]++;
|
114 |
break;
|
115 |
}
|
116 |
case MuonSubdetId::CSC: {
|
117 |
CSCDigiSpec digi(rawId, is->second);
|
118 |
PattCore[GoldenPattern::POSCSC][rawId][digi.strip()]++;
|
119 |
PattCore[GoldenPattern::BENCSC][rawId][digi.pattern()]++;
|
120 |
break;
|
121 |
}
|
122 |
default: {std::cout <<" Unexpeced sebdet case, id ="<<is->first <<std::endl; return; }
|
123 |
};
|
124 |
}
|
125 |
}
|
126 |
|
127 |
GoldenPattern::Result GoldenPattern::compare(const Pattern &p) const
|
128 |
{
|
129 |
Result result;
|
130 |
const Pattern::DataType & detdigi = p;
|
131 |
uint32_t nTot = 0;
|
132 |
///Check spatial compatibility of GP with Pattern.
|
133 |
///Require at least 5 measurements in common detUnits
|
134 |
for (auto is = detdigi.cbegin(); is != detdigi.cend(); ++is) {
|
135 |
uint32_t rawId = is->first;
|
136 |
for(auto mType = PattCore.cbegin();mType!=PattCore.cend();++mType){
|
137 |
nTot+=mType->second.count(rawId);
|
138 |
}
|
139 |
}
|
140 |
if(nTot<5) return result;
|
141 |
/////////////////////////////////////////////////////////////////////
|
142 |
|
143 |
SystFreq::const_iterator cit;
|
144 |
DetFreq::const_iterator idm;
|
145 |
PosBenCase mType;
|
146 |
for (auto is = detdigi.cbegin(); is != detdigi.cend(); ++is) {
|
147 |
uint32_t rawId = is->first;
|
148 |
DetId detId(rawId);
|
149 |
if (detId.det() != DetId::Muon){
|
150 |
std::cout << "GoldenPattern::compare PROBLEM: hit in unknown Det, detID: "<<detId.det()<<std::endl;
|
151 |
return result;
|
152 |
}
|
153 |
if (detId.subdetId() == MuonSubdetId::RPC) {
|
154 |
RPCDigiSpec digi(rawId, is->second);
|
155 |
mType = GoldenPattern::POSRPC;
|
156 |
cit = PattCore.find(mType);
|
157 |
if(cit==PattCore.cend()) return result; //AK: Ugly, FIX.
|
158 |
idm = cit->second.find(rawId);
|
159 |
if (idm != cit->second.cend() ) {
|
160 |
float f = whereInDistribution(digi.halfStrip(), idm->second);
|
161 |
result.myResults[mType].push_back(std::make_pair(rawId, f));
|
162 |
RPCDetId rpc(rawId);
|
163 |
if(rpc.station()==1) result.hasStation1 = true;
|
164 |
if(rpc.station()==2) result.hasStation2 = true;
|
165 |
}
|
166 |
}
|
167 |
else if (detId.subdetId() == MuonSubdetId::DT) {
|
168 |
DTphDigiSpec digi(rawId, is->second);
|
169 |
mType = GoldenPattern::POSDT;
|
170 |
cit = PattCore.find(mType);
|
171 |
if(cit==PattCore.cend()) return result;
|
172 |
idm = cit->second.find(rawId);
|
173 |
if (idm != cit->second.cend() ) {
|
174 |
float f = whereInDistribution(digi.phi(), idm->second);
|
175 |
result.myResults[mType].push_back(std::make_pair(rawId, f));
|
176 |
DTChamberId dt(rawId);
|
177 |
if(dt.station()==1) result.hasStation1 = true;
|
178 |
if(dt.station()==2) result.hasStation2 = true;
|
179 |
}
|
180 |
mType = GoldenPattern::BENDT;
|
181 |
cit = PattCore.find(mType);
|
182 |
if(cit==PattCore.cend()) return result;
|
183 |
idm = cit->second.find(rawId);
|
184 |
if (idm != cit->second.cend() ) {
|
185 |
float f = whereInDistribution(digi.phiB(), idm->second);
|
186 |
result.myResults[mType].push_back(std::make_pair(rawId, f));
|
187 |
}
|
188 |
}
|
189 |
else if (detId.subdetId() == MuonSubdetId::CSC) {
|
190 |
CSCDigiSpec digi(rawId, is->second);
|
191 |
mType = GoldenPattern::POSCSC;
|
192 |
cit = PattCore.find(mType);
|
193 |
if(cit==PattCore.cend()) return result;
|
194 |
auto idm = cit->second.find(rawId);
|
195 |
if (idm != cit->second.cend() ) {
|
196 |
float f = whereInDistribution(digi.strip(), idm->second);
|
197 |
result.myResults[mType].push_back(std::make_pair(rawId, f));
|
198 |
CSCDetId csc(rawId);
|
199 |
if (csc.station()==1) result.hasStation1 = true;
|
200 |
if (csc.station()==2) result.hasStation1 = true;
|
201 |
}
|
202 |
mType = GoldenPattern::BENCSC;
|
203 |
cit = PattCore.find(mType);
|
204 |
if(cit==PattCore.cend()) return result;
|
205 |
idm = cit->second.find(rawId);
|
206 |
if (idm != cit->second.cend() ) {
|
207 |
float f = whereInDistribution(digi.pattern(), idm->second);
|
208 |
result.myResults[mType].push_back(std::make_pair(rawId, f));
|
209 |
}
|
210 |
}
|
211 |
}
|
212 |
|
213 |
return result;
|
214 |
}
|
215 |
|
216 |
float GoldenPattern::whereInDistribution( int obj, const GoldenPattern::MFreq & m) const
|
217 |
{
|
218 |
|
219 |
float sum_before = 0;
|
220 |
float sum_after = 0;
|
221 |
float sum_obj = 0;
|
222 |
for (MFreq::const_iterator im = m.begin(); im != m.end(); ++im) {
|
223 |
if (im->first < obj) sum_before+= im->second;
|
224 |
if (im->first == obj) sum_obj = im->second;
|
225 |
if (im->first > obj) sum_after += im->second;
|
226 |
}
|
227 |
float sum = std::max((float)1.,sum_before+sum_after+sum_obj );
|
228 |
//return sum_obj/sum; //AK
|
229 |
return (sum_before+sum_obj/2.)/sum;
|
230 |
}
|
231 |
|
232 |
bool GoldenPattern::purge(){
|
233 |
|
234 |
bool remove = false;
|
235 |
int pos;
|
236 |
unsigned int bef2, bef1, aft1, aft2, aft3;
|
237 |
for (auto isf=PattCore.begin();isf!=PattCore.end();){
|
238 |
for (auto idf = isf->second.begin(); idf !=isf->second.end();) {
|
239 |
for (auto imf = idf->second.begin(); imf != idf->second.end();) {
|
240 |
remove = false;
|
241 |
pos = imf->first;
|
242 |
bef2 = (idf->second.find(pos-2) != idf->second.end()) ? idf->second[pos-2] : 0;
|
243 |
bef1 = (idf->second.find(pos-1) != idf->second.end()) ? idf->second[pos-1] : 0;
|
244 |
aft1 = (idf->second.find(pos+1) != idf->second.end()) ? idf->second[pos+1] : 0;
|
245 |
aft2 = (idf->second.find(pos+2) != idf->second.end()) ? idf->second[pos+2] : 0;
|
246 |
aft3 = (idf->second.find(pos+3) != idf->second.end()) ? idf->second[pos+3] : 0;
|
247 |
if (idf->second[pos]==1 && bef1==0 && aft1==0) remove = true;
|
248 |
if (idf->second[pos]==1 && aft1==1 && aft2==0 && aft3==0 && bef1==0 && bef2==0) remove = true;
|
249 |
if (idf->second[pos]==2 && aft1==0 && aft2==0 && bef1==0 && bef2==0) remove = true;
|
250 |
//if(remove) std::cout<<"Cleaning pattern: "<<*this<<std::endl;
|
251 |
if(remove) {idf->second.erase(imf++); } else { ++imf; }
|
252 |
}
|
253 |
if (idf->second.size()==0) isf->second.erase(idf++); else ++idf;
|
254 |
}
|
255 |
if (isf->second.size()==0) PattCore.erase(isf++); else ++isf;
|
256 |
}
|
257 |
///Usefull pattern has at least 4 measurements and has a RPC measurement
|
258 |
return PattCore.find(POSRPC)!=PattCore.end() && PattCore.size()>4;
|
259 |
}
|
260 |
|
261 |
std::ostream & operator << (std::ostream &out, const GoldenPattern & o) {
|
262 |
|
263 |
out <<"GoldenPattern"<< o.theKey <<std::endl;
|
264 |
|
265 |
std::vector<std::string> typeInfos = {"POSRPC","POSCSC","BENCSC","POSDT","BENDT"};
|
266 |
|
267 |
for (auto isf=o.PattCore.cbegin();isf!=o.PattCore.cend();++isf){
|
268 |
for (auto idf = isf->second.cbegin(); idf!=isf->second.cend();++idf) {
|
269 |
out <<typeInfos[isf->first]<<" Det: "<< idf->first;
|
270 |
if(typeInfos[isf->first].find("RPC")!=std::string::npos){
|
271 |
RPCDetId rpc(idf->first);
|
272 |
out<<" ("<<rpc<<") ";
|
273 |
}
|
274 |
if(typeInfos[isf->first].find("CSC")!=std::string::npos){
|
275 |
CSCDetId csc(idf->first);
|
276 |
out<<" ("<<csc<<") ";
|
277 |
}
|
278 |
if(typeInfos[isf->first].find("DT")!=std::string::npos){
|
279 |
DTChamberId dt(idf->first);
|
280 |
out<<" ("<<dt<<") ";
|
281 |
}
|
282 |
out <<" Value: ";
|
283 |
for (auto imf = idf->second.cbegin(); imf != idf->second.cend();++imf)
|
284 |
{ out << imf->first<<":"<<imf->second<<", "; }
|
285 |
out << std::endl;
|
286 |
}
|
287 |
}
|
288 |
return out;
|
289 |
}
|
290 |
|