#include <AlgChopListSharp2.h>
Inheritance diagram for AlgChopListSharp2:

Public Member Functions | |
| AlgChopListSharp2 () | |
| virtual | ~AlgChopListSharp2 () |
| virtual void | RunAlg (AlgConfig &ac, CandHandle &ch, CandContext &cx) |
| virtual void | Trace (const char *c) const |
Private Member Functions | |
| bool | ShouldSplit (float this_ph, float next_ph, float d_tmax) |
|
|
Definition at line 48 of file AlgChopListSharp2.cxx. 00049 {
00050 }
|
|
|
Definition at line 53 of file AlgChopListSharp2.cxx. 00054 {
00055 }
|
|
||||||||||||||||
|
Algorithm to chop by using the summed energy waveform of the whole calorimeter. Implements AlgBase. Definition at line 115 of file AlgChopListSharp2.cxx. References CandHandle::AddDaughterLink(), digits(), done(), RawRecord::FindRawBlock(), Form(), AlgFactory::GetAlgHandle(), PlexSEIdAltL::GetBestSEId(), CandContext::GetCandRecord(), CandContext::GetDataIn(), VldContext::GetDetector(), MomNavigator::GetFragment(), AlgFactory::GetInstance(), CandContext::GetMom(), PlexPlaneId::GetPlane(), CandDigitHandle::GetPlexSEIdAltL(), Calibrator::GetTDCFromTime(), CandDigitHandle::GetTime(), RecMinos::GetVldContext(), Calibrator::Instance(), kQieRcid, PlexPlaneId::LastPlaneNearCalor(), CandDigitList::MakeCandidate(), MSG, CandHandle::SetName(), and ShouldSplit(). 00118 {
00122
00123 // Config.
00124 bool cDoRecombobulation = false;
00125
00126 assert(candHandle.InheritsFrom("CandChopListHandle"));
00127 CandChopListHandle &chopList = dynamic_cast<CandChopListHandle &>(candHandle);
00128
00129 assert(candContext.GetDataIn());
00130 // Check for CandDigitListHandle input
00131 if (!(candContext.GetDataIn()->InheritsFrom("CandDigitListHandle"))) {
00132 MSG("Chop",Msg::kWarning ) << "Data into AlgChopListSharp2 is not a digit list." << std::endl;
00133 }
00134
00135 const CandDigitListHandle *cdlh_ptr =
00136 dynamic_cast<const CandDigitListHandle*>(candContext.GetDataIn());
00137
00138 const MomNavigator *mom = candContext.GetMom();
00139 RawRecord *rr = dynamic_cast<RawRecord *>(mom->GetFragment("RawRecord"));
00140 if (!rr) {
00141 MSG("Chop", Msg::kWarning) << "No RawRecord in MOM." << endl;
00142 return;
00143 }
00144 const RawDigitDataBlock *rddb = dynamic_cast<const RawDigitDataBlock *>
00145 (rr->FindRawBlock("RawDigitDataBlock"));
00146 if (!rddb) {
00147 MSG("Chop", Msg::kWarning) << "No RawDigitDataBlock in RawRecord." << endl;
00148 return;
00149 }
00150
00151 // Get setup for the DigitList maker algorithm
00152 AlgFactory &af = AlgFactory::GetInstance();
00153 AlgHandle ah = af.GetAlgHandle("AlgChop","default");
00154 CandContext cxx(this,candContext.GetMom());
00155
00156 const VldContext &context = *(candContext.GetCandRecord()->GetVldContext());
00157 if(context.GetDetector() != DetectorType::kNear)
00158 MSG("Chop",Msg::kError) << "Running the Sharp2 algorithm on FD data is a no-no!" << endl;
00159
00160 Calibrator& cal = Calibrator::Instance();
00161 UgliGeomHandle ugli(context);
00162
00163 // Now do the actual slicing.
00164
00165 // First, make a nice stl vector of the digits.
00166 DigitVector digits(cdlh_ptr);
00167
00168 UInt_t ndigits = digits.size();
00169 UInt_t nchop = 0;
00170
00171 // Sort the list by time.
00172 // Not neccessary for this algorithm.
00173 // std::sort(digits.begin(), digits.end(), compareDigitTimes());
00174
00175
00176 // Also, I want some other pieces of info:
00177 std::vector<int> digit_tdc(ndigits);
00178 std::vector<UInt_t> digit_plane(ndigits);
00179 //std::vector<float> digit_tpos(ndigits);
00180 for(UInt_t i=0;i<ndigits;i++) {
00181 digit_tdc[i] = (cal.GetTDCFromTime(digits[i].GetTime(CalTimeType::kNone), kQieRcid));
00182 digit_plane[i] = digits[i].GetPlexSEIdAltL().GetPlane();
00183 //if(digit_plane[i]<=PlexPlaneId::LastPlaneNearCalor())
00184 // digit_tpos[i] = ugli.GetStripHandle(digits[i].GetPlexSEIdAltL().GetBestSEId()).GetTPos();
00185 //else
00186 // digit_tpos[i] = -999;
00187 }
00188
00189 // Find first and last times. Add some padding so sertain operations are easier to code.
00190 Int_t tfirst = digit_tdc[0];
00191 Int_t tlast = digit_tdc[0];
00192 for(UInt_t i=0;i<ndigits;i++) {
00193 if(digit_tdc[i] < tfirst) tfirst = digit_tdc[i];
00194 if(digit_tdc[i] > tlast ) tlast = digit_tdc[i];
00195 }
00196 tfirst-=5;
00197 tlast +=5;
00198
00199
00200 // Make the energy histogram.
00201 MSG("Chop",Msg::kDebug) << "Running Chop_Sharp2" << endl;
00202
00203 UInt_t numBins = tlast-tfirst;
00204
00205 // Create the energy-time profile.
00206 std::vector<float> energyVsTime(numBins,0.);
00207
00208 for(UInt_t idig = 0; idig < ndigits; idig++ ) {
00209 float sigcor = digits[idig].GetCharge(CalDigitType::kSigCorr);
00210 int tdcbin = digit_tdc[idig]-tfirst;
00211 if((tdcbin<0) || ((int)numBins<=tdcbin)) MSG("Chop",Msg::kDebug) << "Whups!" << endl;
00212 else if(digit_plane[idig]<=PlexPlaneId::LastPlaneNearCalor()) {
00213 energyVsTime[digit_tdc[idig]-tfirst] += sigcor;
00214 }
00215 }
00216
00217
00218
00219 std::vector<int> cuts;
00220 /*
00221 cuts.push_back(0); // cut at start.
00222 int peak_bin = 0;
00223 bool rising = true;
00224 for(UInt_t bin=0;bin<numBins-1;bin++) {
00225 float dq = energyVsTime[bin+1] - energyVsTime[bin];
00226 float max_climb = 2.5*sqrt(fabs(energyVsTime[bin])/k1pe)*k1pe;
00227 if(max_climb < 4.*k1pe) max_climb = max_climb*2.;
00228
00229 bool falling = !rising;
00230
00231 if(falling && ((bin-peak_bin)<8))
00232 if(max_climb<5.*k1pe) max_climb = 5.*k1pe;
00233
00234 if(falling) {
00235 if(dq > max_climb){
00236 cuts.push_back(bin);
00237 rising = true;
00238 }
00239 }
00240
00241 if(rising) {
00242 if(dq< 0){
00243 rising = false;
00244 peak_bin = bin;
00245 }
00246 }
00247 }
00248
00249 cuts.push_back(numBins-1); // cut at the end.
00250 */
00251
00252 // Used bins:
00253 std::vector<char> binsUsed(numBins,0);
00254 binsUsed[0]=1;
00255 binsUsed[numBins-1]=1;
00256
00257 cuts.push_back(0);
00258 cuts.push_back(numBins-1);
00259
00260
00261
00262 do {
00263 // Look for biggest peak.
00264 UInt_t biggest_bin = 99999;
00265 float biggest_size = 0;
00266 for(UInt_t i=0;i<numBins;i++) {
00267 if(binsUsed[i]==0)
00268 if(energyVsTime[i]>biggest_size) {
00269 biggest_size = energyVsTime[i];
00270 biggest_bin = i;
00271 }
00272 }
00273
00274 if(biggest_bin==99999) break; // We've gone through all of them.
00275 if(biggest_size<=0.) break; // We've hit rock bottom.
00276
00277 // Collect the start and stop time for this chop.
00278 // Start 1 bin before the peak, and at least 1 bin after the peak.
00279 UInt_t bin_start = biggest_bin;
00280 UInt_t bin_stop = biggest_bin;
00281
00282 if(binsUsed[bin_start-1]==0) bin_start--;
00283 if(binsUsed[bin_stop +1]==0) bin_stop++;
00284
00285 bool done = false;
00286 while(!done) {
00287
00288 // Stop if there's a rise. If so, mark as a contested bin.
00289 if(ShouldSplit(energyVsTime[bin_start],
00290 energyVsTime[bin_start-1],
00291 bin_start-1 - biggest_bin ) ) {
00292 done = true;
00293 cuts.push_back(bin_start);
00294 }
00295
00296 // Stop if we've hit another chop.
00297 if(binsUsed[bin_start-1]) {
00298 done = true;
00299 }
00300
00301 if(!done) {
00302 bin_start--;
00303 }
00304 };
00305
00306 // Expand forwards until the energy starts climbing.
00307 // But, allow small pulses in for the first 5 buckets.
00308 done = false;
00309 while(!done) {
00310
00311 // Allow 5 buckets worth of small stuff:
00312 if((energyVsTime[bin_stop+1] < 500.) && (bin_stop+1 < biggest_bin+7)) {
00313 // keep going
00314 } else {
00315 if(ShouldSplit(energyVsTime[bin_stop],
00316 energyVsTime[bin_stop+1],
00317 bin_stop+1 - biggest_bin) ) {
00318 done = true;
00319 cuts.push_back(bin_stop); // mark this one as contested.
00320 }
00321 }
00322
00323 // Stop if we hit another chop.
00324 if(binsUsed[bin_stop+1]) {
00325 //MSG("Chop",Msg::kDebug) << "Didn't move forward; hit another chop." << endl;
00326 done = true;
00327 }
00328
00329 // If we're ok, increment and continue.
00330 if(!done) bin_stop++;
00331 }
00332
00333 // Zero out these buckets so they won't be caught again.
00334 for(UInt_t i=bin_start; i<=bin_stop; i++) {
00335 binsUsed[i] = 1;
00336 }
00337
00338 } while(true);
00339
00340
00341 // Time-order the cuts.
00342 std::sort(cuts.begin(), cuts.end());
00343
00344 // One chop for every cut, corresponding to the cut that ends the chop.
00345 std::vector<Chop> chops(cuts.size());
00346
00347 // Build initial cuts, excluding hits in contested bins.
00348 // loop cuts, 1 to n
00349 for(UInt_t icut = 1; icut<= cuts.size(); icut++) {
00350 int bin_start = cuts[icut-1]+1; // Excluding last contested bin
00351 int bin_stop = cuts[icut]-1; // Excluding current contested bin.
00352
00353 int tdc_start = bin_start + tfirst;
00354 int tdc_stop = bin_stop + tfirst;
00355
00356 for(UInt_t idig = 0; idig < ndigits; idig++ ) {
00357 int tdc = digit_tdc[idig];
00358 if((tdc>=(int)tdc_start)&&(tdc<=(int)tdc_stop)) {
00359 chops[icut].Add(digits[idig]);
00360 }
00361 }
00362 }
00363
00364 // Now loop through again and deal with any contested bins.
00365 // Ignore the first and last cuts, since they are at the start
00366 // and end of the event.
00367 for(UInt_t icut = 1; icut< cuts.size()-1; icut++) {
00368 int contested_bin = cuts[icut];
00369 int contested_tdc = contested_bin + tfirst;
00370
00371 // Make a list of digits in the contested bin.
00372 DigitVector contested_digits;
00373 for(UInt_t idig = 0; idig < ndigits; idig++ ) {
00374 int tdc = digit_tdc[idig];
00375 if(tdc==contested_tdc) {
00376 contested_digits.push_back(digits[idig]);
00377 }
00378 }
00379
00380 if(contested_digits.size()>0) {
00381 // only bother if there's actually some digits in the contested bin.
00382
00383 int chop1 = icut;
00384 int chop2 = icut+1;
00385
00386 // Tell the fighting chops to build maps.
00387 chops[chop1].BuildMaps();
00388 chops[chop2]. BuildMaps();
00389
00390 MSG("Chop",Msg::kDebug) << "Dealing with contested bin " << cuts[icut]
00391 << " with " << contested_digits.size() << " contested digits." << endl;
00392
00393 int assign_strip1 = 0;
00394 int assign_strip2 = 0;
00395 int assign_plane1 = 0;
00396 int assign_plane2 = 0;
00397 int assign_total1 = 0;
00398 int assign_total2 = 0;
00399
00400
00401 // Now loop through contested digits and assign them:
00402 for(UInt_t ic=0; ic<contested_digits.size(); ic++) {
00403 // Assign to chop with most energy on same strip:
00404 CandDigitHandle digit = contested_digits[ic];
00405 PlexStripEndId seid =digit.GetPlexSEIdAltL().GetBestSEId();
00406 float chop1stripE = chops[chop1].fStripEnergy[seid];
00407 float chop2stripE =chops[chop2 ].fStripEnergy[seid];
00408
00409 /*
00410 MSG("Chop",Msg::kDebug) << " Consider " << seid.AsString() << " q=" << digit.GetCharge(CalDigitType::kSigCorr)
00411 << " chop1(s/p/t) = "
00412 << chops[chop1].fStripEnergy[seid] << "/"
00413 << chops[chop1].fPlaneEnergy[seid.GetPlane()] << "/"
00414 << chops[chop1].fTotalEnergy
00415 << " chop2(s/p/t) = "
00416 << chops[chop2].fStripEnergy[seid] << "/"
00417 << chops[chop2].fPlaneEnergy[seid.GetPlane()] << "/"
00418 << chops[chop2].fTotalEnergy
00419 << endl;
00420 */
00421
00422 if(chop1stripE > chop2stripE){
00423 chops[chop1].Add(digit);
00424 assign_strip1++;
00425 } else if(chop2stripE > chop1stripE){
00426 chops[chop2].Add(digit);
00427 assign_strip2++;
00428 } else {
00429 // Darn. The strip content is the same in both. (probably 0)
00430 // So compare on the plane level:
00431
00432 float chop1planeE = chops[chop1].fPlaneEnergy[seid.GetPlane()];
00433 float chop2planeE = chops[chop2].fPlaneEnergy[seid.GetPlane()];
00434 if(chop1planeE > chop2planeE){
00435 chops[chop1].Add(digit);
00436 assign_plane1++;
00437 } else if(chop2planeE > chop1planeE){
00438 chops[chop2].Add(digit);
00439 assign_plane2++;
00440 } else {
00441
00442 // Ok, so there's nothing in either plane. Assign it to the biggest chop,
00443 // or the earlier one if tied.
00444 if(chops[chop1].fTotalEnergy>=chops[chop2].fTotalEnergy) {
00445 chops[chop1].Add(digit);
00446 assign_total1++;
00447 } else {
00448 chops[chop2].Add(digit);
00449 assign_total2++;
00450 }
00451 }
00452 }
00453 } //uuuuuuugly!
00454
00455
00456 MSG("Chop",Msg::kDebug) << " Assigned by strip: " << assign_strip1 << "/" << assign_strip2
00457 << " by plane: " << assign_plane1 << "/" << assign_plane2
00458 << " by total: " << assign_total1 << "/" << assign_total2
00459 << endl;
00460 }
00461
00462
00463 }
00464
00466 // And now...
00467 // Recombobulate!
00468 if(cDoRecombobulation) {
00469
00470 for(UInt_t ichop=1;ichop<chops.size();ichop++) chops[ichop].BuildMaps();
00471
00472 for(UInt_t icut=1;icut<cuts.size()-1;icut++) {
00473 for(int ilr = 0; ilr<2; ilr++) { //loop left and right
00474 int contested_tdc;
00475 int chopfrom;
00476 int chopto;
00477 if(ilr==0) {
00478 contested_tdc = cuts[icut]-1 + tfirst;
00479 chopfrom = icut;
00480 chopto = icut+1;
00481 } else {
00482 contested_tdc = cuts[icut]+1 + tfirst;
00483 chopfrom = icut+1;
00484 chopto = icut;
00485 }
00486
00487 int moved = 0;
00488
00489 for(UInt_t idig = 0; idig<chops[chopfrom].size(); idig++) {
00490 CandDigitHandle digit = chops[chopfrom][idig];
00491 int tdc = (cal.GetTDCFromTime(digit.GetTime(CalTimeType::kNone), kQieRcid));
00492 if(tdc == contested_tdc) {
00493 PlexStripEndId seid =digit.GetPlexSEIdAltL().GetBestSEId();
00494 float sigcor = digits[idig].GetCharge(CalDigitType::kSigCorr);
00495
00496 // If the chop that owns the digit has no other digits on that strip:
00497 if(chops[chopfrom].fStripEnergy[seid] <= sigcor) {
00498 // If the neigboring chop HAS got some energy on that strip
00499 if(chops[chopto].fStripEnergy[seid] > 0) {
00500 // Then move the digit.
00501 chops[chopto].push_back(digit);
00502 chops[chopfrom].erase(chops[chopfrom].begin() + idig);
00503 idig--; // set so we look at the next element instead of skipping one.
00504 moved++;
00505 }
00506 }
00507 }
00508 }
00509
00510 MSG("Chop",Msg::kDebug) << "Recombobulated " << moved << " digits in bin " << contested_tdc-tfirst
00511 << " from chop " << chopfrom << " to chop " << chopto << endl;
00512 } // End left/right loop
00513 } // End loop over cuts
00514
00515 } // end Recombobulation
00516
00517
00519 // Finally, store the chops.
00520
00521 for(UInt_t ichop=1;ichop<chops.size();ichop++) {
00522
00523 if(chops[ichop].size()>0) {
00524
00525 cxx.SetDataIn(&(chops[ichop]));
00526 CandDigitListHandle chopHandle = CandDigitList::MakeCandidate(ah,cxx);
00527 chopHandle.SetName(Form("Chop %d",ichop));
00528 chopList.AddDaughterLink(chopHandle);
00529
00530 MSG("Chop",Msg::kDebug) << "Creating chop. "
00531 << " Start: " << cuts[ichop-1] << " Stop: " << cuts[ichop]
00532 << " Digits: " << chops[ichop].size()
00533 << endl;
00534
00535 nchop++;
00536 }
00537 }
00538 }
|
|
||||||||||||||||
|
Definition at line 91 of file AlgChopListSharp2.cxx. References k1pe. Referenced by RunAlg(). 00095 {
00096 float climb = next_ph - this_ph;
00097
00098 // the maximum delta that the algorithm will climb before making a new chop
00099 float max_climb = 2.5*sqrt(fabs(this_ph)/k1pe)*k1pe;
00100 if(max_climb < (6 * k1pe)) max_climb=max_climb*2;
00101
00102 // the maximum pulse height in this bin if we're making a new chop.
00103 //const float size_limit = 20 * k1pe;
00104 //const float min_time = 2;
00105
00106 //if(d_tmax < min_time) return false;
00107 //if(this_ph < size_limit) return false;
00108
00109 if( climb >= max_climb ) return true;
00110 else return false;
00111 }
|
|
|
Reimplemented from AlgBase. Definition at line 541 of file AlgChopListSharp2.cxx. 00542 {
00543 }
|
1.3.9.1