#include <RecoLocalMuon/RPCNoise/src/RPCNoise.cc>
Implementation: <simple application="" of="" edfilter>="">
Definition at line 88 of file RPCNoise.cc.
RPCNoise::RPCNoise | ( | const edm::ParameterSet & | pset | ) | [explicit] |
Definition at line 158 of file RPCNoise.cc.
References fillHistograms, edm::ParameterSet::getUntrackedParameter(), histogramFileName, nCSCStripsCut, nCSCWiresCut, nDTDigisCut, and nRPCHitsCut.
00159 { 00160 histogramFileName = pset.getUntrackedParameter<string>("histogramFileName","histos.root"); 00161 fillHistograms = pset.getUntrackedParameter<bool>("fillHistograms",true); 00162 nRPCHitsCut = pset.getUntrackedParameter<int>("nRPCHitsCut",40); 00163 nCSCStripsCut = pset.getUntrackedParameter<int>("nCSCStripsCut",50); 00164 nCSCWiresCut = pset.getUntrackedParameter<int>("nCSCWiresCut",10); 00165 nDTDigisCut = pset.getUntrackedParameter<int>("nDTDigisCut",10); 00166 }
RPCNoise::~RPCNoise | ( | ) |
void RPCNoise::beginJob | ( | const edm::EventSetup & | ) | [private, virtual] |
Reimplemented from edm::EDFilter.
Definition at line 173 of file RPCNoise.cc.
References dOrbit, fDTDigisOut, fDTDigisOutH, fillHistograms, firstOrbit, histogramFileName, hitsVsOrbit, hitsVsSerial, iEvent, iRun, lastOrbit, nDTDigis, nDTDigisH, nDTDigisIn, nDTDigisInH, nDTDigisOut, nDTDigisOutH, nEventsAnalyzed, nEventsSelected, nRPCRecHits, nRPCRecHitsLong, nStrips, nStripsH, nWires, nWiresH, orbitVsSerial, RPCBX, RPCBXH, RPCClSize, RPCClSizeH, rpcCorner, rpcCornerH, rpcCornerVsOrbit, rpcLayer, rpcLayerH, rpcRing, rpcRingH, rpcRingVsOrbit, rpcSector, rpcSectorH, rpcSectorVsOrbit, rpcStation, rpcStationH, rpcStationVsOrbit, t0All, t0AllH, theHistogramFile, and thisOrbit.
00174 { 00175 // initialize variables 00176 nEventsAnalyzed = 0; 00177 nEventsSelected = 0; 00178 iRun = 0; 00179 iEvent = 0; 00180 firstOrbit = lastOrbit = thisOrbit = 0; 00181 00182 if (fillHistograms) { 00183 // Create the root file for the histograms 00184 theHistogramFile = new TFile(histogramFileName.c_str(), "RECREATE"); 00185 theHistogramFile->cd(); 00186 // book histograms 00187 nWires = new TH1F("nWires","number of wire digis", 121, -0.5, 120.5); 00188 nStrips = new TH1F("nStrips","number of strip digis", 201, -0.5, 200.5); 00189 nWiresH = new TH1F("nWiresH","number of wire digis HIGH", 121, -0.5, 120.5); 00190 nStripsH = new TH1F("nStripsH","number of strip digis HIGH", 201, -0.5, 200.5); 00191 nDTDigis = new TH1F("nDTDigis","number of DT digis",201,-0.5,200.5); 00192 nDTDigisH = new TH1F("nDTDigisH","number of DT digis HIGH",201,-0.5,200.5); 00193 nDTDigisIn = new TH1F("nDTDigisIn","N DT digis in window",75,0.,150.); 00194 nDTDigisInH = new TH1F("nDTDigisInH","N DT digis in window HIGH",75,0.,150.); 00195 nDTDigisOut = new TH1F("nDTDigisOut","N DT digis out window",75,0.,150.); 00196 nDTDigisOutH = new TH1F("nDTDigisOutH","N DT digis out window HIGH",75,0.,150.); 00197 fDTDigisOut = new TH1F("fDTDigisOut", "fraction DT digis outside window",55,0.,1.1); 00198 fDTDigisOutH = new TH1F("fDTDigisOutH","fraction DT digis outside window HIGH",55,0.,1.1); 00199 00200 t0All = new TH1F("t0All","t0",700,0.,7000.); 00201 t0AllH = new TH1F("t0AllH","t0 HIGH",700,0.,7000.); 00202 RPCBX = new TH1F("RPCBX","RPC BX",21,-10.5,10.5); 00203 RPCBXH = new TH1F("RPCBXH","RPC BX HIGH",21,-10.5,10.5); 00204 RPCClSize = new TH1F("RPCClSize","RPC cluster size",61,-0.5,60.5); 00205 RPCClSizeH = new TH1F("RPCClSizeH","RPC cluster size HIGH",61,-0.5,60.5); 00206 00207 nRPCRecHits = new TH1F("nRPCRecHits","number of RPC RecHits",101,-0.5,100.5); 00208 nRPCRecHitsLong = new TH1F("nRPCRecHitsLong","number of RPC RecHits",601,-0.5,600.5); 00209 hitsVsSerial = new TProfile("hitsVsSerial","mean RPC hits vs serial event number",4000,0.,40000.,0.,1000.); 00210 orbitVsSerial = new TProfile("orbitVsSerial","relative orbit number vs serial event number",4000,0.,40000.,0.,1.e10); 00211 hitsVsOrbit = new TProfile("hitsVsOrbit","mean RPC hits vs orbit number",3000,0.,1200000.,0.,1000.); 00212 dOrbit = new TH1F("dOrbit","difference in orbit number",121,-0.5,120.5); 00213 00214 rpcStation = new TH1F("rpcStation", "RPC station", 6,-0.5,5.5); 00215 rpcStationH = new TH1F("rpcStationH", "RPC station HIGH", 6,-0.5,5.5); 00216 rpcRing = new TH1F("rpcRing", "RPC ring", 9,-4.5,4.5); 00217 rpcRingH = new TH1F("rpcRingH", "RPC ring HIGH", 9,-4.5,4.5); 00218 rpcSector = new TH1F("rpcSector", "RPC sector", 15,-0.5,14.5); 00219 rpcSectorH = new TH1F("rpcSectorH", "RPC sector HIGH", 15,-0.5,14.5); 00220 rpcLayer = new TH1F("rpcLayer", "RPC layer", 4,-0.5,3.5); 00221 rpcLayerH = new TH1F("rpcLayerH", "RPC layer HIGH", 4,-0.5,3.5); 00222 rpcStationVsOrbit = new TProfile("rpcStationVsOrbit","mean RPC station vs. Orbit",3000,0.,1200000.,0.,20.); 00223 rpcSectorVsOrbit = new TProfile("rpcSectorVsOrbit","mean RPC sector vs. Orbit", 3000,0.,1200000.,0.,20.); 00224 rpcRingVsOrbit = new TProfile("rpcRingVsOrbit","mean RPC ring vs. Orbit", 3000,0.,1200000.,-20.,20.); 00225 rpcCorner = new TH1F("rpcCorner", "special corner designation", 4,-0.5,3.5); 00226 rpcCornerH = new TH1F("rpcCornerH","special corner designation HIGH", 4,-0.5,3.5); 00227 rpcCornerVsOrbit = new TProfile("rpcCornerVsOrbit","special corner vs. Orbit",3000,0.,1200000.,-20.,20.); 00228 } 00229 00230 }
Reimplemented from edm::EDFilter.
Definition at line 234 of file RPCNoise.cc.
References GenMuonPlsPt100GeV_cfg::cout, dOrbit, lat::endl(), fDTDigisOut, fDTDigisOutH, fillHistograms, firstOrbit, hitsVsOrbit, hitsVsSerial, lastOrbit, nDTDigis, nDTDigisH, nDTDigisIn, nDTDigisInH, nDTDigisOut, nDTDigisOutH, nEventsAnalyzed, nEventsSelected, nRPCRecHits, nRPCRecHitsLong, nStrips, nStripsH, nWires, nWiresH, orbitVsSerial, RPCBX, RPCBXH, RPCClSize, RPCClSizeH, rpcCorner, rpcCornerH, rpcCornerVsOrbit, rpcLayer, rpcLayerH, rpcRing, rpcRingH, rpcRingVsOrbit, rpcSector, rpcSectorH, rpcSectorVsOrbit, rpcStation, rpcStationH, rpcStationVsOrbit, t0All, t0AllH, and theHistogramFile.
00234 { 00235 cout << "\n\t===============================================================\n" 00236 << "\tnumber of events analyzed = " << nEventsAnalyzed << endl 00237 << "\tnumber of events selected = " << nEventsSelected << endl 00238 << "\tfirst and last orbit number : " << firstOrbit << ", " << lastOrbit << ", " << lastOrbit-firstOrbit << endl 00239 << "\t===============================================================\n\n"; 00240 00241 00242 if (fillHistograms) { 00243 // Write the histos to file 00244 printf("\n\n======= write out my histograms ====\n\n"); 00245 theHistogramFile->cd(); 00246 nWires->Write(); 00247 nStrips->Write(); 00248 nWiresH->Write(); 00249 nStripsH->Write(); 00250 nDTDigis->Write(); 00251 nDTDigisH->Write(); 00252 nDTDigisIn->Write(); 00253 nDTDigisInH->Write(); 00254 nDTDigisOut->Write(); 00255 nDTDigisOutH->Write(); 00256 fDTDigisOut->Write(); 00257 fDTDigisOutH->Write(); 00258 nRPCRecHits->Write(); 00259 nRPCRecHitsLong->Write(); 00260 hitsVsSerial->Write(); 00261 hitsVsOrbit->Write(); 00262 orbitVsSerial->Write(); 00263 t0All->Write(); 00264 t0AllH->Write(); 00265 RPCBX->Write(); 00266 RPCClSize->Write(); 00267 RPCBXH->Write(); 00268 RPCClSizeH->Write(); 00269 rpcStation->Write(); 00270 rpcStationH->Write(); 00271 rpcRing->Write(); 00272 rpcRingH->Write(); 00273 rpcSector->Write(); 00274 rpcSectorH->Write(); 00275 rpcLayer->Write(); 00276 rpcLayerH->Write(); 00277 dOrbit->Write(); 00278 rpcStationVsOrbit->Write(); 00279 rpcSectorVsOrbit->Write(); 00280 rpcRingVsOrbit->Write(); 00281 rpcCorner->Write(); 00282 rpcCornerH->Write(); 00283 rpcCornerVsOrbit->Write(); 00284 theHistogramFile->Close(); 00285 } 00286 }
bool RPCNoise::filter | ( | edm::Event & | event, | |
const edm::EventSetup & | eventSetup | |||
) | [private, virtual] |
Implements edm::EDFilter.
Definition at line 292 of file RPCNoise.cc.
References GenMuonPlsPt100GeV_cfg::cout, dOrbit, lat::endl(), fDTDigisOut, fDTDigisOutH, fillHistograms, firstOrbit, hitsVsOrbit, hitsVsSerial, iEvent, iRun, lastOrbit, min, nCSCStripsCut, nCSCWiresCut, nDTDigis, nDTDigisCut, nDTDigisH, nDTDigisIn, nDTDigisInH, nDTDigisOut, nDTDigisOutH, nEventsAnalyzed, nEventsSelected, nRPCHitsCut, nRPCRecHits, nRPCRecHitsLong, nStrips, nStripsH, nWires, nWiresH, orbitVsSerial, RPCBX, RPCBXH, RPCClSize, RPCClSizeH, rpcCorner, rpcCornerH, rpcCornerVsOrbit, rpcLayer, rpcLayerH, python::rpcRecHits_cfi::rpcRecHits, rpcRing, rpcRingH, rpcRingVsOrbit, rpcSector, rpcSectorH, rpcSectorVsOrbit, rpcStation, rpcStationH, rpcStationVsOrbit, t0All, t0AllH, and thisOrbit.
00292 { 00293 00294 bool selectThisEvent = false; 00295 00296 // increment counter 00297 nEventsAnalyzed++; 00298 00299 iRun = event.id().run(); 00300 iEvent = event.id().event(); 00301 00302 bool printThisLine = (nEventsAnalyzed%100 == 0); 00303 if (printThisLine) { 00304 cout << "======================================" 00305 << " analyzed= " << nEventsAnalyzed 00306 << ", selected= " << nEventsSelected 00307 << "\trun,event: " << iRun << ", " << iEvent << endl; 00308 } 00309 00310 /* 00311 const edm::Timestamp jTime = event.time(); 00312 unsigned int sec = jTime.value() >> 32; 00313 unsigned int usec = 0xFFFFFFFF & jTime.value() ; 00314 double floatTime = sec + usec/(float)1000000.; 00315 */ 00316 00317 // first event gives 00318 // sec = 1225315493 00319 // orbit = 202375185 00320 // bx = 764 00321 // mtime = 205094517 00322 int bx = event.bunchCrossing(); 00323 int thisOrbit = event.orbitNumber(); 00324 long mTime = 3564*thisOrbit + bx; 00325 if (firstOrbit == 0) { 00326 firstOrbit = thisOrbit; 00327 lastOrbit = thisOrbit; 00328 } 00329 int deltaOrbit = thisOrbit - lastOrbit; 00330 lastOrbit = thisOrbit; 00331 int relativeOrbit = thisOrbit - firstOrbit; 00332 00333 if (fillHistograms) {dOrbit->Fill(deltaOrbit);} 00334 00335 if (nEventsAnalyzed < 200) { 00336 cout << iEvent 00337 // << "\tsec,usec: " << sec << ", " << usec 00338 // << "\tfloatTime= " << setprecision(16) << floatTime 00339 // << "\tctime: " << ctime(sec) 00340 << "\torbit,bx,mTime: " << thisOrbit << "," << bx << "," << mTime 00341 << "\tdelta= " << deltaOrbit 00342 << endl; 00343 } 00344 00345 00346 // ================ 00347 // RPC recHits 00348 // ================ 00349 edm::Handle<RPCRecHitCollection> rpcRecHits; 00350 event.getByLabel("rpcRecHits","",rpcRecHits); 00351 00352 // count the number of RPC rechits 00353 int nRPC = 0; 00354 RPCRecHitCollection::const_iterator rpcIt; 00355 for (rpcIt = rpcRecHits->begin(); rpcIt != rpcRecHits->end(); rpcIt++) { 00356 // RPCDetId id = (RPCDetId)(*rpcIt).rpcId(); 00357 // LocalPoint rhitlocal = (*rpcIt).localPosition(); 00358 nRPC++; 00359 } 00360 00361 // loop again, this time fill histograms 00362 for (rpcIt = rpcRecHits->begin(); rpcIt != rpcRecHits->end(); rpcIt++) { 00363 RPCDetId id = (RPCDetId)(*rpcIt).rpcId(); 00364 int kRegion = id.region(); 00365 int kStation = id.station(); 00366 int kRing = id.ring(); 00367 int kSector = id.sector(); 00368 int kLayer = id.layer(); 00369 int bx = (*rpcIt).BunchX(); 00370 int clSize = (*rpcIt).clusterSize(); 00371 int cornerFlag = 0; 00372 if ( (kStation>3) && (kSector<3) ) { 00373 cornerFlag = 1; 00374 if (kRing < 0) cornerFlag = 2; 00375 } 00376 if (nEventsAnalyzed < 100) { 00377 cout << "Region/Station/Ring/Sector/Layer: " 00378 << kRegion << " / " 00379 << kStation << " / " 00380 << kRing << " / " 00381 << kSector << " / " 00382 << kLayer 00383 << "\tbx,clSize: " << bx << ", " << clSize 00384 << endl; 00385 } 00386 if (fillHistograms) { 00387 RPCBX->Fill(bx); 00388 RPCClSize->Fill(min((float)clSize,(float)60.)); 00389 rpcStation->Fill(kStation); 00390 rpcRing->Fill(kRing); 00391 rpcSector->Fill(kSector); 00392 rpcLayer->Fill(kLayer); 00393 rpcStationVsOrbit->Fill(relativeOrbit,kStation); 00394 rpcSectorVsOrbit->Fill(relativeOrbit,kSector); 00395 rpcRingVsOrbit->Fill(relativeOrbit,kRing); 00396 rpcCorner->Fill(cornerFlag); 00397 rpcCornerVsOrbit->Fill(relativeOrbit,cornerFlag); 00398 if (nRPC > nRPCHitsCut) { 00399 RPCBXH->Fill(bx); 00400 RPCClSizeH->Fill(min((float)clSize,(float)60.)); 00401 rpcStationH->Fill(kStation); 00402 rpcRingH->Fill(kRing); 00403 rpcSectorH->Fill(kSector); 00404 rpcLayerH->Fill(kLayer); 00405 rpcCornerH->Fill(cornerFlag); 00406 } 00407 } 00408 00409 } 00410 00411 00412 // =============== 00413 // CSC DIGIs 00414 // =============== 00415 edm::Handle<CSCWireDigiCollection> wires; 00416 edm::Handle<CSCStripDigiCollection> strips; 00417 event.getByLabel("muonCSCDigis","MuonCSCWireDigi",wires); 00418 event.getByLabel("muonCSCDigis","MuonCSCStripDigi",strips); 00419 00420 // count the number of wire digis. 00421 int nW = 0; 00422 for (CSCWireDigiCollection::DigiRangeIterator jW=wires->begin(); jW!=wires->end(); jW++) { 00423 std::vector<CSCWireDigi>::const_iterator wireIterA = (*jW).second.first; 00424 std::vector<CSCWireDigi>::const_iterator lWireA = (*jW).second.second; 00425 for( ; wireIterA != lWireA; ++wireIterA) { 00426 nW++; 00427 } 00428 } 00429 00430 // count the number of fired strips. 00431 // I am using a crude indicator of signal - this is fast and adequate for 00432 // this purpose, but it would be poor for actual CSC studies. 00433 int nS = 0; 00434 for (CSCStripDigiCollection::DigiRangeIterator jS=strips->begin(); jS!=strips->end(); jS++) { 00435 std::vector<CSCStripDigi>::const_iterator stripItA = (*jS).second.first; 00436 std::vector<CSCStripDigi>::const_iterator lastStripA = (*jS).second.second; 00437 for( ; stripItA != lastStripA; ++stripItA) { 00438 std::vector<int> myADCVals = stripItA->getADCCounts(); 00439 int iDiff = myADCVals[4]+myADCVals[5]-myADCVals[0]-myADCVals[1]; 00440 if (iDiff > 30) { 00441 nS++; 00442 } 00443 } 00444 } 00445 00446 00447 // =============== 00448 // DT DIGIs 00449 // =============== 00450 // see: CalibMuon/DTCalibration/plugins/DTT0Calibration.cc 00451 edm::Handle<DTDigiCollection> dtDIGIs; 00452 event.getByLabel("muonDTDigis",dtDIGIs); 00453 00454 // count the number of digis. 00455 int nDT = 0; 00456 int nDTin = 0; 00457 int nDTout = 0; 00458 for (DTDigiCollection::DigiRangeIterator jDT=dtDIGIs->begin(); jDT!=dtDIGIs->end(); ++jDT) { 00459 const DTDigiCollection::Range& digiRange = (*jDT).second; 00460 for (DTDigiCollection::const_iterator digi = digiRange.first; 00461 digi != digiRange.second; 00462 digi++) { 00463 double t0 = (*digi).countsTDC(); 00464 nDT++; 00465 if ((t0>3050) && (t0<3700)) { 00466 nDTin++; 00467 } else { 00468 nDTout++; 00469 } 00470 if (fillHistograms) { 00471 t0All->Fill(t0); 00472 if (nRPC > nRPCHitsCut) {t0AllH->Fill(t0);} 00473 } 00474 } 00475 } 00476 00477 //============== 00478 // Analysis 00479 //============== 00480 00481 if (nEventsAnalyzed < 1000) {cout << "\tnumber of CSC DIGIS = " << nW << ", " << nS 00482 << "\tDT DIGIS = " << nDT 00483 << "\tRPC Rechits = " << nRPC << endl;} 00484 00485 if (fillHistograms) { 00486 00487 nWires->Fill(min((float)nW,(float)120.)); 00488 nStrips->Fill(min((float)nS,(float)200.)); 00489 00490 nDTDigis->Fill(min((float)nDT,(float)200.)); 00491 nDTDigisIn->Fill(min((float)nDTin,(float)200.)); 00492 nDTDigisOut->Fill(min((float)nDTout,(float)200.)); 00493 if (nDT > 0) { 00494 float fracOut = float(nDTout)/float(nDT); 00495 fDTDigisOut->Fill(fracOut); 00496 } 00497 nRPCRecHits->Fill(min((float)nRPC,(float)100.)); 00498 nRPCRecHitsLong->Fill(min((float)nRPC,(float)1000.)); 00499 hitsVsSerial->Fill(nEventsAnalyzed,nRPC); 00500 hitsVsOrbit->Fill(relativeOrbit,nRPC); 00501 orbitVsSerial->Fill(nEventsAnalyzed,relativeOrbit); 00502 00503 if (nRPC > nRPCHitsCut) { 00504 nWiresH->Fill(min((float)nW,(float)120.)); 00505 nStripsH->Fill(min((float)nS,(float)200.)); 00506 nDTDigisH->Fill(min((float)nDT,(float)200.)); 00507 nDTDigisInH->Fill(min((float)nDTin,(float)200.)); 00508 nDTDigisOutH->Fill(min((float)nDTout,(float)200.)); 00509 if (nDT > 0) { 00510 float fracOut = float(nDTout)/float(nDT); 00511 fDTDigisOutH->Fill(fracOut); 00512 } 00513 } 00514 } 00515 00516 // select this event for output? 00517 00518 selectThisEvent = (nRPC > nRPCHitsCut) && (nW > nCSCWiresCut || nS > nCSCStripsCut) && (nDT > nDTDigisCut); 00519 if (selectThisEvent) {nEventsSelected++;} 00520 00521 return selectThisEvent; 00522 }
TH1F* RPCNoise::dOrbit [private] |
TH1F* RPCNoise::fDTDigisOut [private] |
TH1F* RPCNoise::fDTDigisOutH [private] |
bool RPCNoise::fillHistograms [private] |
Definition at line 107 of file RPCNoise.cc.
Referenced by beginJob(), endJob(), filter(), and RPCNoise().
int RPCNoise::firstOrbit [private] |
std::string RPCNoise::histogramFileName [private] |
TProfile* RPCNoise::hitsVsOrbit [private] |
TProfile* RPCNoise::hitsVsSerial [private] |
int RPCNoise::iEvent [private] |
int RPCNoise::iRun [private] |
int RPCNoise::lastOrbit [private] |
int RPCNoise::nCSCStripsCut [private] |
int RPCNoise::nCSCWiresCut [private] |
TH1F* RPCNoise::nDTDigis [private] |
int RPCNoise::nDTDigisCut [private] |
TH1F* RPCNoise::nDTDigisH [private] |
TH1F* RPCNoise::nDTDigisIn [private] |
TH1F* RPCNoise::nDTDigisInH [private] |
TH1F* RPCNoise::nDTDigisOut [private] |
TH1F* RPCNoise::nDTDigisOutH [private] |
int RPCNoise::nEventsAnalyzed [private] |
int RPCNoise::nEventsSelected [private] |
int RPCNoise::nRPCHitsCut [private] |
TH1F* RPCNoise::nRPCRecHits [private] |
TH1F* RPCNoise::nRPCRecHitsLong [private] |
TH1F* RPCNoise::nStrips [private] |
TH1F* RPCNoise::nStripsH [private] |
TH1F* RPCNoise::nWires [private] |
TH1F* RPCNoise::nWiresH [private] |
TProfile* RPCNoise::orbitVsSerial [private] |
TH1F* RPCNoise::RPCBX [private] |
TH1F* RPCNoise::RPCBXH [private] |
TH1F* RPCNoise::RPCClSize [private] |
TH1F* RPCNoise::RPCClSizeH [private] |
TH1F* RPCNoise::rpcCorner [private] |
TH1F* RPCNoise::rpcCornerH [private] |
TProfile* RPCNoise::rpcCornerVsOrbit [private] |
TH1F* RPCNoise::rpcLayer [private] |
TH1F* RPCNoise::rpcLayerH [private] |
TH1F* RPCNoise::rpcRing [private] |
TH1F* RPCNoise::rpcRingH [private] |
TProfile* RPCNoise::rpcRingVsOrbit [private] |
TH1F* RPCNoise::rpcSector [private] |
TH1F* RPCNoise::rpcSectorH [private] |
TProfile* RPCNoise::rpcSectorVsOrbit [private] |
TH1F* RPCNoise::rpcStation [private] |
TH1F* RPCNoise::rpcStationH [private] |
TProfile* RPCNoise::rpcStationVsOrbit [private] |
TH1F* RPCNoise::t0All [private] |
TH1F* RPCNoise::t0AllH [private] |
TFile* RPCNoise::theHistogramFile [private] |
int RPCNoise::thisOrbit [private] |