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