00001
00002
00003
00004
00005
00007
00008 #include <cassert>
00009 #include <cmath>
00010
00011 #include "CandChop/AlgChopListSharp.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(AlgChopListSharp)
00036 CVSID( " $Id: AlgChopListSharp.cxx,v 1.4 2007/11/11 08:26:13 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(Detector::kNear,ElecType::kQIE,0,0,false,false);
00045 const float k1pe = 100.;
00046
00047
00048
00049 AlgChopListSharp::AlgChopListSharp()
00050 {
00051 }
00052
00053
00054 AlgChopListSharp::~AlgChopListSharp()
00055 {
00056 }
00057
00058
00059 bool AlgChopListSharp::ShouldSplit( float this_ph,
00060 float next_ph,
00061 float
00062 )
00063 {
00064 float climb = next_ph - this_ph;
00065
00066
00067 float max_climb = 2.5*sqrt(fabs(this_ph)/k1pe)*k1pe;
00068 if(max_climb < (6 * k1pe)) max_climb=max_climb*2;
00069
00070
00071
00072
00073
00074
00075
00076
00077 if( climb >= max_climb ) return true;
00078 else return false;
00079 }
00080
00081
00082
00083 void AlgChopListSharp::RunAlg(AlgConfig& ,
00084 CandHandle &candHandle,
00085 CandContext &candContext)
00086 {
00090
00091 assert(candHandle.InheritsFrom("CandChopListHandle"));
00092 CandChopListHandle &chopList = dynamic_cast<CandChopListHandle &>(candHandle);
00093
00094 assert(candContext.GetDataIn());
00095
00096 if (!(candContext.GetDataIn()->InheritsFrom("CandDigitListHandle"))) {
00097 MSG("Chop",Msg::kWarning ) << "Data into AlgChopListSharp is not a digit list." << std::endl;
00098 }
00099
00100 const CandDigitListHandle *cdlh_ptr =
00101 dynamic_cast<const CandDigitListHandle*>(candContext.GetDataIn());
00102
00103 const MomNavigator *mom = candContext.GetMom();
00104 RawRecord *rr = dynamic_cast<RawRecord *>(mom->GetFragment("RawRecord"));
00105 if (!rr) {
00106 MSG("Chop", Msg::kWarning) << "No RawRecord in MOM." << endl;
00107 return;
00108 }
00109 const RawDigitDataBlock *rddb = dynamic_cast<const RawDigitDataBlock *>
00110 (rr->FindRawBlock("RawDigitDataBlock"));
00111 if (!rddb) {
00112 MSG("Chop", Msg::kWarning) << "No RawDigitDataBlock in RawRecord." << endl;
00113 return;
00114 }
00115
00116
00117 AlgFactory &af = AlgFactory::GetInstance();
00118 AlgHandle ah = af.GetAlgHandle("AlgChop","default");
00119 CandContext cxx(this,candContext.GetMom());
00120
00121 const VldContext &context = *(candContext.GetCandRecord()->GetVldContext());
00122 if(context.GetDetector() != Detector::kNear)
00123 MSG("Chop",Msg::kError) << "Running the Sharp algorithm on FD data is a no-no!" << endl;
00124
00125 Calibrator& cal = Calibrator::Instance();
00126 UgliGeomHandle ugli(context);
00127
00128
00129
00130
00131 DigitVector digits(cdlh_ptr);
00132
00133 UInt_t ndigits = digits.size();
00134 UInt_t nchop = 0;
00135
00136
00137
00138
00139
00140
00141
00142 std::vector<int> digit_tdc(ndigits);
00143 std::vector<UInt_t> digit_plane(ndigits);
00144
00145 for(UInt_t i=0;i<ndigits;i++) {
00146 digit_tdc[i] = (cal.GetTDCFromTime(digits[i].GetTime(CalTimeType::kNone), kQieRcid));
00147 digit_plane[i] = digits[i].GetPlexSEIdAltL().GetPlane();
00148
00149
00150
00151
00152 }
00153
00154
00155 Int_t tfirst = digit_tdc[0];
00156 Int_t tlast = digit_tdc[0];
00157 for(UInt_t i=0;i<ndigits;i++) {
00158 if(digit_tdc[i] < tfirst) tfirst = digit_tdc[i];
00159 if(digit_tdc[i] > tlast ) tlast = digit_tdc[i];
00160 }
00161 tfirst-=5;
00162 tlast +=5;
00163
00164
00165
00166 MSG("Chop",Msg::kDebug) << "Running Chop_Sharp" << endl;
00167
00168 UInt_t numBins = tlast-tfirst;
00169
00170
00171 std::vector<float> energyVsTime(numBins,0.);
00172
00173 for(UInt_t idig = 0; idig < ndigits; idig++ ) {
00174 float sigcor = digits[idig].GetCharge(CalDigitType::kSigCorr);
00175 int tdcbin = digit_tdc[idig]-tfirst;
00176 if((tdcbin<0) || ((int)numBins<=tdcbin)) MSG("Chop",Msg::kDebug) << "Whups!" << endl;
00177 else if(digit_plane[idig]<=PlexPlaneId::LastPlaneNearCalor()) {
00178 energyVsTime[digit_tdc[idig]-tfirst] += sigcor;
00179 }
00180 }
00181
00182
00183 std::vector<char> binsUsed(numBins,0);
00184
00185 do {
00186
00187 UInt_t biggest_bin = 99999;
00188 float biggest_size = 0;
00189 for(UInt_t i=0;i<numBins;i++) {
00190 if(binsUsed[i]==0)
00191 if(energyVsTime[i]>biggest_size) {
00192 biggest_size = energyVsTime[i];
00193 biggest_bin = i;
00194 }
00195 }
00196
00197 if(biggest_bin==99999) break;
00198 if(biggest_size<100.) break;
00199
00200
00201
00202 UInt_t bin_start = biggest_bin;
00203 UInt_t bin_stop = biggest_bin;
00204
00205
00206
00207
00208
00209 if(binsUsed[bin_start-1]==0) bin_start--;
00210 if(binsUsed[bin_stop +1]==0) bin_stop++;
00211
00212 bool done = false;
00213 while(!done) {
00214
00215 if(bin_start==0) {
00216
00217 done=true;
00218 }
00219
00220 if(ShouldSplit(energyVsTime[bin_start],
00221 energyVsTime[bin_start-1],
00222 bin_start-1 - biggest_bin ) ) {
00223
00224 done = true;
00225 }
00226
00227
00228 if(binsUsed[bin_start-1]) {
00229
00230 done = true;
00231 }
00232
00233 if(!done) {
00234
00235 bin_start--;
00236 }
00237 };
00238
00239
00240
00241 done = false;
00242 while(!done) {
00243
00244 if(bin_stop >= numBins-1) {
00245
00246 done = true;
00247 }
00248
00249
00250 if((energyVsTime[bin_stop+1] < 500.) && (bin_stop+1 < biggest_bin+7)) {
00251
00252 } else {
00253 if(ShouldSplit(energyVsTime[bin_stop],
00254 energyVsTime[bin_stop+1],
00255 bin_stop+1 - biggest_bin) ) {
00256
00257 done = true;
00258 }
00259 }
00260
00261
00262 if(binsUsed[bin_stop+1]) {
00263
00264 done = true;
00265 }
00266
00267
00268 if(!done) bin_stop++;
00269 }
00270
00271 int tdc_start = bin_start+tfirst;
00272 int tdc_stop = bin_stop+tfirst;
00273
00274
00275 DigitVector slc;
00276
00277 for(UInt_t idig = 0; idig < ndigits; idig++ ) {
00278 int tdc = digit_tdc[idig];
00279 if((tdc>=(int)tdc_start)&&(tdc<=(int)tdc_stop))
00280 slc.push_back(digits[idig]);
00281 }
00282 cxx.SetDataIn(&(slc));
00283 CandDigitListHandle chopHandle = CandDigitList::MakeCandidate(ah,cxx);
00284 chopHandle.SetName(Form("Chop %d",nchop++));
00285 chopList.AddDaughterLink(chopHandle);
00286
00287 MSG("Chop",Msg::kDebug) << "Creating chop. Big: " << biggest_bin
00288 << " Start: " << bin_start << " Stop: " << bin_stop
00289 << " Digits: " << slc.size()
00290 << endl;
00291
00292
00293
00294
00295 for(UInt_t i=bin_start; i<=bin_stop; i++) {
00296 binsUsed[i] = 1;
00297 }
00298
00299 } while(true);
00300
00301 }
00302
00303
00304 void AlgChopListSharp::Trace(const char * ) const
00305 {
00306 }
00307