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