00001
00002
00003
00004
00005
00007
00008 #include <cassert>
00009
00010 #include "CandChop/AlgChopListSharp2.h"
00011 #include "CandChop/CandChopListHandle.h"
00012 #include "CandChop/DigitVector.h"
00013
00014
00015 #include "Algorithm/AlgConfig.h"
00016 #include "Algorithm/AlgFactory.h"
00017 #include "Algorithm/AlgHandle.h"
00018 #include "CandData/CandHeader.h"
00019 #include "CandData/CandRecord.h"
00020 #include "CandDigit/CandDigitHandle.h"
00021 #include "CandDigit/CandDigitListHandle.h"
00022 #include "CandDigit/CandDigitList.h"
00023 #include "Candidate/CandContext.h"
00024 #include "MessageService/MsgService.h"
00025 #include "MinosObjectMap/MomNavigator.h"
00026 #include "RawData/RawHeader.h"
00027 #include "RawData/RawRecord.h"
00028 #include "RawData/RawDigitDataBlock.h"
00029 #include "UgliGeometry/UgliGeomHandle.h"
00030 #include "UgliGeometry/UgliStripHandle.h"
00031 #include "Validity/VldContext.h"
00032 #include "Calibrator/Calibrator.h"
00033
00034 ClassImp(AlgChopListSharp2)
00035 CVSID( " $Id: AlgChopListSharp2.cxx,v 1.2 2005/05/19 17:55:33 tagg Exp $ ");
00036
00037 struct compareDigitTimes : public binary_function<const CandDigitHandle&, const CandDigitHandle&, bool> {
00038 bool operator()(const CandDigitHandle& d1, const CandDigitHandle& d2) {
00039 return (d1.GetTime() < d2.GetTime());
00040 }
00041 };
00042
00043 const RawChannelId kQieRcid(DetectorType::kNear,ElecType::kQIE,0,0,false,false);
00044 const float k1pe = 100.;
00045
00046
00047
00048 AlgChopListSharp2::AlgChopListSharp2()
00049 {
00050 }
00051
00052
00053 AlgChopListSharp2::~AlgChopListSharp2()
00054 {
00055 }
00056
00057 class Chop : public DigitVector{
00058 public:
00059 std::map<PlexStripEndId,float> fStripEnergy;
00060 std::map<int, float> fPlaneEnergy;
00061 float fTotalEnergy;
00062 bool fDirty;
00063
00064 Chop() : fDirty(false) {};
00065
00066 void Add(CandDigitHandle& cdh) {
00067 fDirty = true;
00068 push_back(cdh);
00069 }
00070
00071 void BuildMaps() {
00072 if(fDirty) {
00073 fStripEnergy.clear();
00074 fPlaneEnergy.clear();
00075 fTotalEnergy = 0;
00076 for(UInt_t i=0;i<size();i++) {
00077 float sigcor = (*this)[i].GetCharge(CalDigitType::kSigCorr);
00078 PlexStripEndId seid = (*this)[i].GetPlexSEIdAltL().GetBestSEId();
00079 if(seid.IsValid()) {
00080 fStripEnergy[seid] += sigcor;
00081 fPlaneEnergy[seid.GetPlane()] += sigcor;
00082 fTotalEnergy += sigcor;
00083 }
00084 }
00085 }
00086 fDirty = false;
00087 }
00088 };
00089
00090
00091 bool AlgChopListSharp2::ShouldSplit( float this_ph,
00092 float next_ph,
00093 float
00094 )
00095 {
00096 float climb = next_ph - this_ph;
00097
00098
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
00103
00104
00105
00106
00107
00108
00109 if( climb >= max_climb ) return true;
00110 else return false;
00111 }
00112
00113
00114
00115 void AlgChopListSharp2::RunAlg(AlgConfig& ,
00116 CandHandle &candHandle,
00117 CandContext &candContext)
00118 {
00122
00123
00124 bool cDoRecombobulation = false;
00125
00126 assert(candHandle.InheritsFrom("CandChopListHandle"));
00127 CandChopListHandle &chopList = dynamic_cast<CandChopListHandle &>(candHandle);
00128
00129 assert(candContext.GetDataIn());
00130
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
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
00164
00165
00166 DigitVector digits(cdlh_ptr);
00167
00168 UInt_t ndigits = digits.size();
00169 UInt_t nchop = 0;
00170
00171
00172
00173
00174
00175
00176
00177 std::vector<int> digit_tdc(ndigits);
00178 std::vector<UInt_t> digit_plane(ndigits);
00179
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
00184
00185
00186
00187 }
00188
00189
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
00201 MSG("Chop",Msg::kDebug) << "Running Chop_Sharp2" << endl;
00202
00203 UInt_t numBins = tlast-tfirst;
00204
00205
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
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 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
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;
00275 if(biggest_size<=0.) break;
00276
00277
00278
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
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
00297 if(binsUsed[bin_start-1]) {
00298 done = true;
00299 }
00300
00301 if(!done) {
00302 bin_start--;
00303 }
00304 };
00305
00306
00307
00308 done = false;
00309 while(!done) {
00310
00311
00312 if((energyVsTime[bin_stop+1] < 500.) && (bin_stop+1 < biggest_bin+7)) {
00313
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);
00320 }
00321 }
00322
00323
00324 if(binsUsed[bin_stop+1]) {
00325
00326 done = true;
00327 }
00328
00329
00330 if(!done) bin_stop++;
00331 }
00332
00333
00334 for(UInt_t i=bin_start; i<=bin_stop; i++) {
00335 binsUsed[i] = 1;
00336 }
00337
00338 } while(true);
00339
00340
00341
00342 std::sort(cuts.begin(), cuts.end());
00343
00344
00345 std::vector<Chop> chops(cuts.size());
00346
00347
00348
00349 for(UInt_t icut = 1; icut<= cuts.size(); icut++) {
00350 int bin_start = cuts[icut-1]+1;
00351 int bin_stop = cuts[icut]-1;
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
00365
00366
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
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
00382
00383 int chop1 = icut;
00384 int chop2 = icut+1;
00385
00386
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
00402 for(UInt_t ic=0; ic<contested_digits.size(); ic++) {
00403
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
00411
00412
00413
00414
00415
00416
00417
00418
00419
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
00430
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
00443
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 }
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
00467
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++) {
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
00497 if(chops[chopfrom].fStripEnergy[seid] <= sigcor) {
00498
00499 if(chops[chopto].fStripEnergy[seid] > 0) {
00500
00501 chops[chopto].push_back(digit);
00502 chops[chopfrom].erase(chops[chopfrom].begin() + idig);
00503 idig--;
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 }
00513 }
00514
00515 }
00516
00517
00519
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 }
00539
00540
00541 void AlgChopListSharp2::Trace(const char * ) const
00542 {
00543 }
00544