00001 #include "SimCalorimetry/HcalTrigPrimAlgos/interface/HcalTriggerPrimitiveAlgo.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003
00004 #include <iostream>
00005 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00006 #include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h"
00007 #include "DataFormats/HcalDetId/interface/HcalTrigTowerDetId.h"
00008 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00009 #include "DataFormats/HcalDetId/interface/HcalElectronicsId.h"
00010 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
00011 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
00012
00013 using namespace std;
00014
00015 HcalTriggerPrimitiveAlgo::HcalTriggerPrimitiveAlgo( bool pf, const std::vector<double>& w, int latency,
00016 uint32_t FG_threshold, uint32_t ZS_threshold,
00017 int numberOfSamples, int numberOfPresamples,
00018 uint32_t minSignalThreshold, uint32_t PMT_NoiseThreshold)
00019 : incoder_(0), outcoder_(0),
00020 theThreshold(0), peakfind_(pf), weights_(w), latency_(latency),
00021 FG_threshold_(FG_threshold), ZS_threshold_(ZS_threshold),
00022 numberOfSamples_(numberOfSamples),
00023 numberOfPresamples_(numberOfPresamples),
00024 minSignalThreshold_(minSignalThreshold),
00025 PMT_NoiseThreshold_(PMT_NoiseThreshold),
00026 peak_finder_algorithm_(2)
00027 {
00028
00029 if (!peakfind_){
00030 numberOfSamples_ = 1;
00031 numberOfPresamples_ = 0;
00032 }
00033
00034 ZS_threshold_I_ = ZS_threshold_;
00035 }
00036
00037
00038 HcalTriggerPrimitiveAlgo::~HcalTriggerPrimitiveAlgo() {
00039 }
00040
00041
00042 void HcalTriggerPrimitiveAlgo::run(const HcalTPGCoder* incoder,
00043 const HcalTPGCompressor* outcoder,
00044 const HBHEDigiCollection& hbheDigis,
00045 const HFDigiCollection& hfDigis,
00046 HcalTrigPrimDigiCollection& result,
00047 const HcalTrigTowerGeometry* trigTowerGeometry,
00048 float rctlsb) {
00049 theTrigTowerGeometry = trigTowerGeometry;
00050
00051 incoder_=dynamic_cast<const HcaluLUTTPGCoder*>(incoder);
00052 outcoder_=outcoder;
00053
00054 theSumMap.clear();
00055 theTowerMapFGSum.clear();
00056 HF_Veto.clear();
00057 fgMap_.clear();
00058
00059
00060 for(HBHEDigiCollection::const_iterator hbheItr = hbheDigis.begin();
00061 hbheItr != hbheDigis.end(); ++hbheItr) {
00062 addSignal(*hbheItr);
00063 }
00064
00065
00066 for(HFDigiCollection::const_iterator hfItr = hfDigis.begin();
00067 hfItr != hfDigis.end(); ++hfItr) {
00068 addSignal(*hfItr);
00069
00070 }
00071
00072 for(SumMap::iterator mapItr = theSumMap.begin(); mapItr != theSumMap.end(); ++mapItr) {
00073 result.push_back(HcalTriggerPrimitiveDigi(mapItr->first));
00074 HcalTrigTowerDetId detId(mapItr->second.id());
00075 if(detId.ietaAbs() >= theTrigTowerGeometry->firstHFTower())
00076 { analyzeHF(mapItr->second, result.back(), rctlsb);}
00077 else{analyze(mapItr->second, result.back());}
00078 }
00079 return;
00080 }
00081
00082
00083 void HcalTriggerPrimitiveAlgo::addSignal(const HBHEDataFrame & frame) {
00084
00085 if (frame.id().depth()==5) return;
00086
00087 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(frame.id());
00088 assert(ids.size() == 1 || ids.size() == 2);
00089 IntegerCaloSamples samples1(ids[0], int(frame.size()));
00090
00091 samples1.setPresamples(frame.presamples());
00092 incoder_->adc2Linear(frame, samples1);
00093
00094 std::vector<bool> msb;
00095 incoder_->lookupMSB(frame, msb);
00096
00097 if(ids.size() == 2) {
00098
00099 IntegerCaloSamples samples2(ids[1], samples1.size());
00100 for(int i = 0; i < samples1.size(); ++i) {
00101 samples1[i] = uint32_t(samples1[i]*0.5);
00102 samples2[i] = samples1[i];
00103 }
00104 samples2.setPresamples(frame.presamples());
00105 addSignal(samples2);
00106 addFG(ids[1], msb);
00107 }
00108 addSignal(samples1);
00109 addFG(ids[0], msb);
00110 }
00111
00112
00113 void HcalTriggerPrimitiveAlgo::addSignal(const HFDataFrame & frame) {
00114
00115 if(frame.id().depth() == 1 || frame.id().depth() == 2) {
00116 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(frame.id());
00117 assert(ids.size() == 1);
00118 IntegerCaloSamples samples(ids[0], frame.size());
00119 samples.setPresamples(frame.presamples());
00120 incoder_->adc2Linear(frame, samples);
00121
00122
00123
00124 IntegerCaloSamples zero_samples(ids[0], frame.size());
00125 zero_samples.setPresamples(frame.presamples());
00126 addSignal(zero_samples);
00127
00128
00129 uint32_t fgid = (frame.id().rawId() | 0x1c000) ;
00130
00131 if ( theTowerMapFGSum.find(ids[0]) == theTowerMapFGSum.end() ) {
00132 SumFGContainer sumFG;
00133 theTowerMapFGSum.insert(std::pair<HcalTrigTowerDetId, SumFGContainer >(ids[0], sumFG));
00134 }
00135
00136 SumFGContainer& sumFG = theTowerMapFGSum[ids[0]];
00137 SumFGContainer::iterator sumFGItr;
00138 for ( sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
00139 if (sumFGItr->id() == fgid) break;
00140 }
00141
00142 if (sumFGItr != sumFG.end()) {
00143 for (int i=0; i<samples.size(); ++i) (*sumFGItr)[i] += samples[i];
00144 }
00145 else {
00146
00147 IntegerCaloSamples sumFGSamples(DetId(fgid), samples.size());
00148 sumFGSamples.setPresamples(samples.presamples());
00149 for (int i=0; i<samples.size(); ++i) sumFGSamples[i] = samples[i];
00150 sumFG.push_back(sumFGSamples);
00151 }
00152
00153
00154 if (HF_Veto.find(fgid) == HF_Veto.end()) {
00155 vector<bool> vetoBits(samples.size(), false);
00156 HF_Veto[fgid] = vetoBits;
00157 }
00158 for (int i=0; i<samples.size(); ++i)
00159 if (samples[i] < minSignalThreshold_)
00160 HF_Veto[fgid][i] = true;
00161 }
00162 }
00163
00164
00165 void HcalTriggerPrimitiveAlgo::addSignal(const IntegerCaloSamples & samples) {
00166 HcalTrigTowerDetId id(samples.id());
00167 SumMap::iterator itr = theSumMap.find(id);
00168 if(itr == theSumMap.end()) {
00169 theSumMap.insert(std::make_pair(id, samples));
00170 }
00171 else {
00172
00173 for(int i = 0; i < samples.size(); ++i) {
00174 (itr->second)[i] += samples[i];
00175 }
00176 }
00177 }
00178
00179
00180 void HcalTriggerPrimitiveAlgo::analyze(IntegerCaloSamples & samples, HcalTriggerPrimitiveDigi & result) {
00181 int shrink = weights_.size() - 1;
00182 std::vector<bool> finegrain(numberOfSamples_,false);
00183 std::vector<bool>& msb = fgMap_[samples.id()];
00184 IntegerCaloSamples sum(samples.id(), samples.size());
00185
00186
00187 for(int ibin = 0; ibin < int(samples.size())- shrink; ++ibin) {
00188 int algosumvalue = 0;
00189 for(unsigned int i = 0; i < weights_.size(); i++) {
00190
00191 algosumvalue += int(samples[ibin+i] * weights_[i]);
00192 }
00193 if (algosumvalue<0) sum[ibin]=0;
00194
00195
00196 else sum[ibin] = algosumvalue;
00197 }
00198
00199 IntegerCaloSamples output(samples.id(), numberOfSamples_);
00200 output.setPresamples(numberOfPresamples_);
00201
00202
00203 int shift = samples.presamples() - numberOfPresamples_;
00204 if (peakfind_) {
00205 assert (shift >= (peakfind_ ? shrink : 0));
00206 assert(shift + numberOfSamples_ + shrink <= samples.size() - (peak_finder_algorithm_ - 1));
00207 }
00208
00209
00210 for (int ibin = 0; ibin < numberOfSamples_; ++ibin) {
00211
00212
00213 int idx = ibin + shift;
00214
00215
00216 if (peakfind_) {
00217 bool isPeak = false;
00218 switch (peak_finder_algorithm_) {
00219 case 1 :
00220 isPeak = (samples[idx] > samples[idx-1] && samples[idx] >= samples[idx+1] && samples[idx] > theThreshold);
00221 break;
00222 case 2:
00223 isPeak = (sum[idx] > sum[idx-1] && sum[idx] >= sum[idx+1] && sum[idx] > theThreshold);
00224 break;
00225 default:
00226 break;
00227 }
00228
00229 if (isPeak){
00230 output[ibin] = std::min<unsigned int>(sum[idx],0x3FF);
00231 finegrain[ibin] = msb[idx];
00232 }
00233
00234 else output[ibin] = 0;
00235 }
00236 else {
00237 output[ibin] = std::min<unsigned int>(sum[idx],0x3FF);
00238 finegrain[ibin] = msb[idx];
00239 }
00240
00241
00242 if (peak_finder_algorithm_ == 1) {
00243 if (samples[idx] >= 0x3FF)
00244 output[ibin] = 0x3FF;
00245 }
00246 outcoder_->compress(output, finegrain, result);
00247 }
00248 }
00249
00250
00251 void HcalTriggerPrimitiveAlgo::analyzeHF(IntegerCaloSamples & samples, HcalTriggerPrimitiveDigi & result, float rctlsb) {
00252 std::vector<bool> finegrain(numberOfSamples_, false);
00253 HcalTrigTowerDetId detId(samples.id());
00254
00255
00256 int shift = samples.presamples() - numberOfPresamples_;
00257 assert(shift >= 0);
00258 assert((shift + numberOfSamples_) <= samples.size());
00259
00260 TowerMapFGSum::const_iterator tower2fg = theTowerMapFGSum.find(detId);
00261 assert(tower2fg != theTowerMapFGSum.end());
00262
00263 const SumFGContainer& sumFG = tower2fg->second;
00264
00265
00266 for (SumFGContainer::const_iterator sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
00267 const std::vector<bool>& veto = HF_Veto[sumFGItr->id().rawId()];
00268 for (int ibin = 0; ibin < numberOfSamples_; ++ibin) {
00269 int idx = ibin + shift;
00270
00271 if (!(veto[idx] && (*sumFGItr)[idx] > PMT_NoiseThreshold_)) {
00272 samples[idx] += (*sumFGItr)[idx];
00273 finegrain[ibin] = (finegrain[ibin] || (*sumFGItr)[idx] >= FG_threshold_);
00274 }
00275 }
00276 }
00277
00278 IntegerCaloSamples output(samples.id(), numberOfSamples_);
00279 output.setPresamples(numberOfPresamples_);
00280
00281 for (int ibin = 0; ibin < numberOfSamples_; ++ibin) {
00282 int idx = ibin + shift;
00283 output[ibin] = samples[idx] / (rctlsb == 0.25 ? 4 : 8);
00284 if (output[ibin] > 0x3FF) output[ibin] = 0x3FF;
00285 }
00286 outcoder_->compress(output, finegrain, result);
00287 }
00288
00289 void HcalTriggerPrimitiveAlgo::runZS(HcalTrigPrimDigiCollection & result){
00290 for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
00291 bool ZS = true;
00292 for (int i=0; i<tp->size(); ++i) {
00293 if (tp->sample(i).compressedEt() > ZS_threshold_I_) {
00294 ZS=false;
00295 break;
00296 }
00297 }
00298 if (ZS) tp->setZSInfo(false,true);
00299 else tp->setZSInfo(true,false);
00300 }
00301 }
00302
00303 void HcalTriggerPrimitiveAlgo::runFEFormatError(const FEDRawDataCollection* rawraw,
00304 const HcalElectronicsMap *emap,
00305 HcalTrigPrimDigiCollection & result
00306 ){
00307 std::set<uint32_t> FrontEndErrors;
00308
00309 for(int i=FEDNumbering::MINHCALFEDID; i<=FEDNumbering::MAXHCALFEDID; ++i) {
00310 const FEDRawData& raw = rawraw->FEDData(i);
00311 if (raw.size()<12) continue;
00312 const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00313 if(!dccHeader) continue;
00314 HcalHTRData htr;
00315 for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00316 if (!dccHeader->getSpigotPresent(spigot)) continue;
00317 dccHeader->getSpigotData(spigot,htr,raw.size());
00318 int dccid = dccHeader->getSourceId();
00319 int errWord = htr.getErrorsWord() & 0x1FFFF;
00320 bool HTRError = (!htr.check() || htr.isHistogramEvent() || (errWord & 0x800)!=0);
00321
00322 if(HTRError) {
00323 bool valid =false;
00324 for(int fchan=0; fchan<3 && !valid; fchan++) {
00325 for(int fib=0; fib<9 && !valid; fib++) {
00326 HcalElectronicsId eid(fchan,fib,spigot,dccid-FEDNumbering::MINHCALFEDID);
00327 eid.setHTR(htr.readoutVMECrateId(),htr.htrSlot(),htr.htrTopBottom());
00328 DetId detId = emap->lookup(eid);
00329 if(detId.null()) continue;
00330 HcalSubdetector subdet=(HcalSubdetector(detId.subdetId()));
00331 if (detId.det()!=4||
00332 (subdet!=HcalBarrel && subdet!=HcalEndcap &&
00333 subdet!=HcalForward )) continue;
00334 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
00335 for (std::vector<HcalTrigTowerDetId>::const_iterator triggerId=ids.begin(); triggerId != ids.end(); ++triggerId) {
00336 FrontEndErrors.insert(triggerId->rawId());
00337 }
00338
00339 }
00340 }
00341 }
00342 }
00343 }
00344
00345
00346
00347 HcalTriggerPrimitiveSample zeroSample(0);
00348 for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
00349 if (FrontEndErrors.find(tp->id().rawId()) != FrontEndErrors.end()) {
00350 for (int i=0; i<tp->size(); ++i) tp->setSample(i, zeroSample);
00351 }
00352 }
00353 }
00354
00355 void HcalTriggerPrimitiveAlgo::addFG(const HcalTrigTowerDetId& id, std::vector<bool>& msb){
00356 FGbitMap::iterator itr = fgMap_.find(id);
00357 if (itr != fgMap_.end()){
00358 std::vector<bool>& _msb = itr->second;
00359 for (size_t i=0; i<msb.size(); ++i)
00360 _msb[i] = _msb[i] || msb[i];
00361 }
00362 else fgMap_[id] = msb;
00363 }
00364
00365 void HcalTriggerPrimitiveAlgo::setPeakFinderAlgorithm(int algo){
00366 if (algo <=0 && algo>2)
00367 throw cms::Exception("ERROR: Only algo 1 & 2 are supported.") << std::endl;
00368 peak_finder_algorithm_ = algo;
00369 }