00001
00002
00003
00004
00005
00007
00008 #include <cassert>
00009 #include <cmath>
00010
00011 #include "CandChop/AlgChopListSharp2.h"
00012 #include "CandChop/CandChopListHandle.h"
00013 #include "CandChop/DigitVector.h"
00014
00015
00016 #include "Algorithm/AlgConfig.h"
00017 #include "Algorithm/AlgFactory.h"
00018 #include "Algorithm/AlgHandle.h"
00019 #include "CandData/CandHeader.h"
00020 #include "CandData/CandRecord.h"
00021 #include "CandDigit/CandDigitHandle.h"
00022 #include "CandDigit/CandDigitListHandle.h"
00023 #include "CandDigit/CandDigitList.h"
00024 #include "Candidate/CandContext.h"
00025 #include "MessageService/MsgService.h"
00026 #include "MinosObjectMap/MomNavigator.h"
00027 #include "RawData/RawHeader.h"
00028 #include "RawData/RawRecord.h"
00029 #include "RawData/RawDigitDataBlock.h"
00030 #include "UgliGeometry/UgliGeomHandle.h"
00031 #include "UgliGeometry/UgliStripHandle.h"
00032 #include "Validity/VldContext.h"
00033 #include "Calibrator/Calibrator.h"
00034
00035 ClassImp(AlgChopListSharp2)
00036 CVSID( " $Id: AlgChopListSharp2.cxx,v 1.3 2006/12/01 18:33:03 rhatcher Exp $ ");
00037
00038 struct compareDigitTimes : public binary_function<const CandDigitHandle&, const CandDigitHandle&, bool> {
00039 bool operator()(const CandDigitHandle& d1, const CandDigitHandle& d2) {
00040 return (d1.GetTime() < d2.GetTime());
00041 }
00042 };
00043
00044 const RawChannelId kQieRcid(DetectorType::kNear,ElecType::kQIE,0,0,false,false);
00045 const float k1pe = 100.;
00046
00047
00048
00049 AlgChopListSharp2::AlgChopListSharp2()
00050 {
00051 }
00052
00053
00054 AlgChopListSharp2::~AlgChopListSharp2()
00055 {
00056 }
00057
00058 class Chop : public DigitVector{
00059 public:
00060 std::map<PlexStripEndId,float> fStripEnergy;
00061 std::map<int, float> fPlaneEnergy;
00062 float fTotalEnergy;
00063 bool fDirty;
00064
00065 Chop() : fDirty(false) {};
00066
00067 void Add(CandDigitHandle& cdh) {
00068 fDirty = true;
00069 push_back(cdh);
00070 }
00071
00072 void BuildMaps() {
00073 if(fDirty) {
00074 fStripEnergy.clear();
00075 fPlaneEnergy.clear();
00076 fTotalEnergy = 0;
00077 for(UInt_t i=0;i<size();i++) {
00078 float sigcor = (*this)[i].GetCharge(CalDigitType::kSigCorr);
00079 PlexStripEndId seid = (*this)[i].GetPlexSEIdAltL().GetBestSEId();
00080 if(seid.IsValid()) {
00081 fStripEnergy[seid] += sigcor;
00082 fPlaneEnergy[seid.GetPlane()] += sigcor;
00083 fTotalEnergy += sigcor;
00084 }
00085 }
00086 }
00087 fDirty = false;
00088 }
00089 };
00090
00091
00092 bool AlgChopListSharp2::ShouldSplit( float this_ph,
00093 float next_ph,
00094 float
00095 )
00096 {
00097 float climb = next_ph - this_ph;
00098
00099
00100 float max_climb = 2.5*sqrt(fabs(this_ph)/k1pe)*k1pe;
00101 if(max_climb < (6 * k1pe)) max_climb=max_climb*2;
00102
00103
00104
00105
00106
00107
00108
00109
00110 if( climb >= max_climb ) return true;
00111 else return false;
00112 }
00113
00114
00115
00116 void AlgChopListSharp2::RunAlg(AlgConfig& ,
00117 CandHandle &candHandle,
00118 CandContext &candContext)
00119 {
00123
00124
00125 bool cDoRecombobulation = false;
00126
00127 assert(candHandle.InheritsFrom("CandChopListHandle"));
00128 CandChopListHandle &chopList = dynamic_cast<CandChopListHandle &>(candHandle);
00129
00130 assert(candContext.GetDataIn());
00131
00132 if (!(candContext.GetDataIn()->InheritsFrom("CandDigitListHandle"))) {
00133 MSG("Chop",Msg::kWarning ) << "Data into AlgChopListSharp2 is not a digit list." << std::endl;
00134 }
00135
00136 const CandDigitListHandle *cdlh_ptr =
00137 dynamic_cast<const CandDigitListHandle*>(candContext.GetDataIn());
00138
00139 const MomNavigator *mom = candContext.GetMom();
00140 RawRecord *rr = dynamic_cast<RawRecord *>(mom->GetFragment("RawRecord"));
00141 if (!rr) {
00142 MSG("Chop", Msg::kWarning) << "No RawRecord in MOM." << endl;
00143 return;
00144 }
00145 const RawDigitDataBlock *rddb = dynamic_cast<const RawDigitDataBlock *>
00146 (rr->FindRawBlock("RawDigitDataBlock"));
00147 if (!rddb) {
00148 MSG("Chop", Msg::kWarning) << "No RawDigitDataBlock in RawRecord." << endl;
00149 return;
00150 }
00151
00152
00153 AlgFactory &af = AlgFactory::GetInstance();
00154 AlgHandle ah = af.GetAlgHandle("AlgChop","default");
00155 CandContext cxx(this,candContext.GetMom());
00156
00157 const VldContext &context = *(candContext.GetCandRecord()->GetVldContext());
00158 if(context.GetDetector() != DetectorType::kNear)
00159 MSG("Chop",Msg::kError) << "Running the Sharp2 algorithm on FD data is a no-no!" << endl;
00160
00161 Calibrator& cal = Calibrator::Instance();
00162 UgliGeomHandle ugli(context);
00163
00164
00165
00166
00167 DigitVector digits(cdlh_ptr);
00168
00169 UInt_t ndigits = digits.size();
00170 UInt_t nchop = 0;
00171
00172
00173
00174
00175
00176
00177
00178 std::vector<int> digit_tdc(ndigits);
00179 std::vector<UInt_t> digit_plane(ndigits);
00180
00181 for(UInt_t i=0;i<ndigits;i++) {
00182 digit_tdc[i] = (cal.GetTDCFromTime(digits[i].GetTime(CalTimeType::kNone), kQieRcid));
00183 digit_plane[i] = digits[i].GetPlexSEIdAltL().GetPlane();
00184
00185
00186
00187
00188 }
00189
00190
00191 Int_t tfirst = digit_tdc[0];
00192 Int_t tlast = digit_tdc[0];
00193 for(UInt_t i=0;i<ndigits;i++) {
00194 if(digit_tdc[i] < tfirst) tfirst = digit_tdc[i];
00195 if(digit_tdc[i] > tlast ) tlast = digit_tdc[i];
00196 }
00197 tfirst-=5;
00198 tlast +=5;
00199
00200
00201
00202 MSG("Chop",Msg::kDebug) << "Running Chop_Sharp2" << endl;
00203
00204 UInt_t numBins = tlast-tfirst;
00205
00206
00207 std::vector<float> energyVsTime(numBins,0.);
00208
00209 for(UInt_t idig = 0; idig < ndigits; idig++ ) {
00210 float sigcor = digits[idig].GetCharge(CalDigitType::kSigCorr);
00211 int tdcbin = digit_tdc[idig]-tfirst;
00212 if((tdcbin<0) || ((int)numBins<=tdcbin)) MSG("Chop",Msg::kDebug) << "Whups!" << endl;
00213 else if(digit_plane[idig]<=PlexPlaneId::LastPlaneNearCalor()) {
00214 energyVsTime[digit_tdc[idig]-tfirst] += sigcor;
00215 }
00216 }
00217
00218
00219
00220 std::vector<int> cuts;
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 std::vector<char> binsUsed(numBins,0);
00255 binsUsed[0]=1;
00256 binsUsed[numBins-1]=1;
00257
00258 cuts.push_back(0);
00259 cuts.push_back(numBins-1);
00260
00261
00262
00263 do {
00264
00265 UInt_t biggest_bin = 99999;
00266 float biggest_size = 0;
00267 for(UInt_t i=0;i<numBins;i++) {
00268 if(binsUsed[i]==0)
00269 if(energyVsTime[i]>biggest_size) {
00270 biggest_size = energyVsTime[i];
00271 biggest_bin = i;
00272 }
00273 }
00274
00275 if(biggest_bin==99999) break;
00276 if(biggest_size<=0.) break;
00277
00278
00279
00280 UInt_t bin_start = biggest_bin;
00281 UInt_t bin_stop = biggest_bin;
00282
00283 if(binsUsed[bin_start-1]==0) bin_start--;
00284 if(binsUsed[bin_stop +1]==0) bin_stop++;
00285
00286 bool done = false;
00287 while(!done) {
00288
00289
00290 if(ShouldSplit(energyVsTime[bin_start],
00291 energyVsTime[bin_start-1],
00292 bin_start-1 - biggest_bin ) ) {
00293 done = true;
00294 cuts.push_back(bin_start);
00295 }
00296
00297
00298 if(binsUsed[bin_start-1]) {
00299 done = true;
00300 }
00301
00302 if(!done) {
00303 bin_start--;
00304 }
00305 };
00306
00307
00308
00309 done = false;
00310 while(!done) {
00311
00312
00313 if((energyVsTime[bin_stop+1] < 500.) && (bin_stop+1 < biggest_bin+7)) {
00314
00315 } else {
00316 if(ShouldSplit(energyVsTime[bin_stop],
00317 energyVsTime[bin_stop+1],
00318 bin_stop+1 - biggest_bin) ) {
00319 done = true;
00320 cuts.push_back(bin_stop);
00321 }
00322 }
00323
00324
00325 if(binsUsed[bin_stop+1]) {
00326
00327 done = true;
00328 }
00329
00330
00331 if(!done) bin_stop++;
00332 }
00333
00334
00335 for(UInt_t i=bin_start; i<=bin_stop; i++) {
00336 binsUsed[i] = 1;
00337 }
00338
00339 } while(true);
00340
00341
00342
00343 std::sort(cuts.begin(), cuts.end());
00344
00345
00346 std::vector<Chop> chops(cuts.size());
00347
00348
00349
00350 for(UInt_t icut = 1; icut<= cuts.size(); icut++) {
00351 int bin_start = cuts[icut-1]+1;
00352 int bin_stop = cuts[icut]-1;
00353
00354 int tdc_start = bin_start + tfirst;
00355 int tdc_stop = bin_stop + tfirst;
00356
00357 for(UInt_t idig = 0; idig < ndigits; idig++ ) {
00358 int tdc = digit_tdc[idig];
00359 if((tdc>=(int)tdc_start)&&(tdc<=(int)tdc_stop)) {
00360 chops[icut].Add(digits[idig]);
00361 }
00362 }
00363 }
00364
00365
00366
00367
00368 for(UInt_t icut = 1; icut< cuts.size()-1; icut++) {
00369 int contested_bin = cuts[icut];
00370 int contested_tdc = contested_bin + tfirst;
00371
00372
00373 DigitVector contested_digits;
00374 for(UInt_t idig = 0; idig < ndigits; idig++ ) {
00375 int tdc = digit_tdc[idig];
00376 if(tdc==contested_tdc) {
00377 contested_digits.push_back(digits[idig]);
00378 }
00379 }
00380
00381 if(contested_digits.size()>0) {
00382
00383
00384 int chop1 = icut;
00385 int chop2 = icut+1;
00386
00387
00388 chops[chop1].BuildMaps();
00389 chops[chop2]. BuildMaps();
00390
00391 MSG("Chop",Msg::kDebug) << "Dealing with contested bin " << cuts[icut]
00392 << " with " << contested_digits.size() << " contested digits." << endl;
00393
00394 int assign_strip1 = 0;
00395 int assign_strip2 = 0;
00396 int assign_plane1 = 0;
00397 int assign_plane2 = 0;
00398 int assign_total1 = 0;
00399 int assign_total2 = 0;
00400
00401
00402
00403 for(UInt_t ic=0; ic<contested_digits.size(); ic++) {
00404
00405 CandDigitHandle digit = contested_digits[ic];
00406 PlexStripEndId seid =digit.GetPlexSEIdAltL().GetBestSEId();
00407 float chop1stripE = chops[chop1].fStripEnergy[seid];
00408 float chop2stripE =chops[chop2 ].fStripEnergy[seid];
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 if(chop1stripE > chop2stripE){
00424 chops[chop1].Add(digit);
00425 assign_strip1++;
00426 } else if(chop2stripE > chop1stripE){
00427 chops[chop2].Add(digit);
00428 assign_strip2++;
00429 } else {
00430
00431
00432
00433 float chop1planeE = chops[chop1].fPlaneEnergy[seid.GetPlane()];
00434 float chop2planeE = chops[chop2].fPlaneEnergy[seid.GetPlane()];
00435 if(chop1planeE > chop2planeE){
00436 chops[chop1].Add(digit);
00437 assign_plane1++;
00438 } else if(chop2planeE > chop1planeE){
00439 chops[chop2].Add(digit);
00440 assign_plane2++;
00441 } else {
00442
00443
00444
00445 if(chops[chop1].fTotalEnergy>=chops[chop2].fTotalEnergy) {
00446 chops[chop1].Add(digit);
00447 assign_total1++;
00448 } else {
00449 chops[chop2].Add(digit);
00450 assign_total2++;
00451 }
00452 }
00453 }
00454 }
00455
00456
00457 MSG("Chop",Msg::kDebug) << " Assigned by strip: " << assign_strip1 << "/" << assign_strip2
00458 << " by plane: " << assign_plane1 << "/" << assign_plane2
00459 << " by total: " << assign_total1 << "/" << assign_total2
00460 << endl;
00461 }
00462
00463
00464 }
00465
00467
00468
00469 if(cDoRecombobulation) {
00470
00471 for(UInt_t ichop=1;ichop<chops.size();ichop++) chops[ichop].BuildMaps();
00472
00473 for(UInt_t icut=1;icut<cuts.size()-1;icut++) {
00474 for(int ilr = 0; ilr<2; ilr++) {
00475 int contested_tdc;
00476 int chopfrom;
00477 int chopto;
00478 if(ilr==0) {
00479 contested_tdc = cuts[icut]-1 + tfirst;
00480 chopfrom = icut;
00481 chopto = icut+1;
00482 } else {
00483 contested_tdc = cuts[icut]+1 + tfirst;
00484 chopfrom = icut+1;
00485 chopto = icut;
00486 }
00487
00488 int moved = 0;
00489
00490 for(UInt_t idig = 0; idig<chops[chopfrom].size(); idig++) {
00491 CandDigitHandle digit = chops[chopfrom][idig];
00492 int tdc = (cal.GetTDCFromTime(digit.GetTime(CalTimeType::kNone), kQieRcid));
00493 if(tdc == contested_tdc) {
00494 PlexStripEndId seid =digit.GetPlexSEIdAltL().GetBestSEId();
00495 float sigcor = digits[idig].GetCharge(CalDigitType::kSigCorr);
00496
00497
00498 if(chops[chopfrom].fStripEnergy[seid] <= sigcor) {
00499
00500 if(chops[chopto].fStripEnergy[seid] > 0) {
00501
00502 chops[chopto].push_back(digit);
00503 chops[chopfrom].erase(chops[chopfrom].begin() + idig);
00504 idig--;
00505 moved++;
00506 }
00507 }
00508 }
00509 }
00510
00511 MSG("Chop",Msg::kDebug) << "Recombobulated " << moved << " digits in bin " << contested_tdc-tfirst
00512 << " from chop " << chopfrom << " to chop " << chopto << endl;
00513 }
00514 }
00515
00516 }
00517
00518
00520
00521
00522 for(UInt_t ichop=1;ichop<chops.size();ichop++) {
00523
00524 if(chops[ichop].size()>0) {
00525
00526 cxx.SetDataIn(&(chops[ichop]));
00527 CandDigitListHandle chopHandle = CandDigitList::MakeCandidate(ah,cxx);
00528 chopHandle.SetName(Form("Chop %d",ichop));
00529 chopList.AddDaughterLink(chopHandle);
00530
00531 MSG("Chop",Msg::kDebug) << "Creating chop. "
00532 << " Start: " << cuts[ichop-1] << " Stop: " << cuts[ichop]
00533 << " Digits: " << chops[ichop].size()
00534 << endl;
00535
00536 nchop++;
00537 }
00538 }
00539 }
00540
00541
00542 void AlgChopListSharp2::Trace(const char * ) const
00543 {
00544 }
00545