00001
00002
00003
00004
00005
00007
00008 #include <cassert>
00009 #include <cmath>
00010
00011 #include "CandChop/AlgChopListMitre.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 #include <TMath.h>
00037
00038 ClassImp(AlgChopListMitre)
00039 CVSID( " $Id: AlgChopListMitre.cxx,v 1.6 2010/01/06 17:15:44 rhatcher Exp $ ");
00040
00041 struct compareDigitTimes : public binary_function<const CandDigitHandle&, const CandDigitHandle&, bool> {
00042 bool operator()(const CandDigitHandle& d1, const CandDigitHandle& d2) {
00043 return (d1.GetTime() < d2.GetTime());
00044 }
00045 };
00046
00047 const RawChannelId kQieRcid(Detector::kNear,ElecType::kQIE,0,0,false,false);
00048 const float k1pe = 100.;
00049
00050
00051
00052 AlgChopListMitre::AlgChopListMitre()
00053 {
00054 }
00055
00056
00057 AlgChopListMitre::~AlgChopListMitre()
00058 {
00059 }
00060
00061
00062
00063
00064 void AlgChopListMitre::RunAlg(AlgConfig& ,
00065 CandHandle &candHandle,
00066 CandContext &candContext)
00067 {
00071
00072 assert(candHandle.InheritsFrom("CandChopListHandle"));
00073 CandChopListHandle &chopList = dynamic_cast<CandChopListHandle &>(candHandle);
00074
00075 assert(candContext.GetDataIn());
00076
00077 if (!(candContext.GetDataIn()->InheritsFrom("CandDigitListHandle"))) {
00078 MSG("Chop",Msg::kWarning ) << "Data into AlgChopListSharp2 is not a digit list." << std::endl;
00079 }
00080
00081 const CandDigitListHandle *cdlh_ptr =
00082 dynamic_cast<const CandDigitListHandle*>(candContext.GetDataIn());
00083
00084 const MomNavigator *mom = candContext.GetMom();
00085 const RawDigitDataBlock* rddb = DataUtil::GetRawBlock<RawDigitDataBlock>(mom);
00086 if (!rddb) {
00087 MSG("Chop", Msg::kWarning) << "No RawDigitDataBlock in RawRecord." << endl;
00088 return;
00089 }
00090
00091
00092 AlgFactory &af = AlgFactory::GetInstance();
00093 AlgHandle ah = af.GetAlgHandle("AlgChop","default");
00094 CandContext cxx(this,candContext.GetMom());
00095
00096 const VldContext &context = *(candContext.GetCandRecord()->GetVldContext());
00097 if(context.GetDetector() != Detector::kNear)
00098 MSG("Chop",Msg::kError) << "Running the Sharp2 algorithm on FD data is a no-no!" << endl;
00099
00100 Calibrator& cal = Calibrator::Instance();
00101 UgliGeomHandle ugli(context);
00102
00103
00104
00105
00106 DigitVector digits(cdlh_ptr);
00107
00108 UInt_t ndigits = digits.size();
00109 UInt_t nchop = 0;
00110
00111
00112
00113
00114
00115
00116
00117 std::vector<int> digit_tdc(ndigits);
00118 std::vector<UInt_t> digit_plane(ndigits);
00119
00120 for(UInt_t i=0;i<ndigits;i++) {
00121 digit_tdc[i] = (cal.GetTDCFromTime(digits[i].GetTime(CalTimeType::kNone), kQieRcid));
00122 digit_plane[i] = digits[i].GetPlexSEIdAltL().GetPlane();
00123
00124
00125
00126
00127 }
00128
00129
00130 Int_t tfirst = digit_tdc[0];
00131 Int_t tlast = digit_tdc[0];
00132 for(UInt_t i=0;i<ndigits;i++) {
00133 if(digit_tdc[i] < tfirst) tfirst = digit_tdc[i];
00134 if(digit_tdc[i] > tlast ) tlast = digit_tdc[i];
00135 }
00136 tfirst-=5;
00137 tlast +=5;
00138
00139
00140
00141 MSG("Chop",Msg::kDebug) << "Running Chop_Sharp2" << endl;
00142
00143 UInt_t numBins = tlast-tfirst;
00144
00145
00146
00147 std::vector< float > profAngles;
00148 profAngles.push_back(0);
00149 profAngles.push_back(1.0/60.);
00150 profAngles.push_back(-1.0/60.);
00151 UInt_t nProf = profAngles.size();
00152
00153 std::vector< std::vector<float> >profiles(nProf);
00154 std::vector<float> meanPlane(numBins,0);
00155
00156
00157 for(UInt_t p = 0; p<nProf; p++) {
00158 profiles[p].resize(numBins,0.);
00159 }
00160
00161 for(UInt_t idig = 0; idig < ndigits; idig++ ) {
00162 float sigcor = digits[idig].GetCharge(CalDigitType::kSigCorr);
00163 float tdcbin = digit_tdc[idig]-tfirst;
00164 float dplane = digit_plane[idig];
00165 if(dplane>PlexPlaneId::LastPlaneNearCalor())
00166 dplane = PlexPlaneId::LastPlaneNearCalor();
00167 dplane = dplane-60.;
00168
00169 std::vector<int> proj(nProf);
00170 for(UInt_t p = 0; p<nProf; p++)
00171 proj[p] = TMath::Nint(tdcbin + profAngles[p]*dplane);
00172
00173 if((tdcbin<0) || ((int)numBins<=tdcbin)) MSG("Chop",Msg::kDebug) << "Whups!" << endl;
00174 else if(digit_plane[idig]<=PlexPlaneId::LastPlaneNearCalor()) {
00175 meanPlane[proj[0]] += dplane*sigcor;
00176
00177 for(UInt_t p = 0; p<nProf; p++) {
00178 profiles[p][proj[p]] += sigcor;
00179 }
00180 }
00181 }
00182
00183 for(UInt_t i=0;i<numBins;i++) meanPlane[i] /= profiles[0][i];
00184
00185
00186 std::vector<int> cuts;
00187 std::vector<int> cuts_type;
00188
00189
00190 cuts.push_back(0);
00191 cuts_type.push_back(0);
00192
00193
00194 int peak_bin = 0;
00195 bool rising = true;
00196 for(UInt_t bin=1;bin<numBins-1;bin++) {
00197 float dq = profiles[0][bin+1] - profiles[0][bin];
00198 float max_climb = 2.5*sqrt(fabs(profiles[0][bin])/k1pe)*k1pe;
00199 if(max_climb < 4.*k1pe) max_climb = max_climb*2.;
00200
00201 bool falling = !rising;
00202
00203 if(falling && ((bin-peak_bin)<8))
00204 if(max_climb<5.*k1pe) max_climb = 5.*k1pe;
00205
00206 if(falling) {
00207 if(dq > max_climb){
00208 cuts.push_back(bin);
00209 cuts_type.push_back(0);
00210 rising = true;
00211 }
00212 }
00213
00214 if(rising) {
00215 if(dq< 0){
00216 rising = false;
00217 peak_bin = bin;
00218 }
00219 }
00220 }
00221
00222
00223
00224 for(UInt_t icut=0;icut<cuts.size(); icut++) {
00225
00226 float lowest_size = profiles[0][cuts[icut]];
00227 if(lowest_size>0) {
00228
00229 MSG("Chop",Msg::kDebug) << "Evaluating cut " << icut
00230 << " at bin " << cuts[icut] << " mean plane " << meanPlane[cuts[icut]] << endl;
00231
00232 int a = cuts[icut]-5; if(a<0) a=0;
00233 int b = cuts[icut]+5; if(b>=(int)numBins) b=numBins-1;
00234 for(int i=a; i<=b; i++) {
00235 MSG("Chop",Msg::kDebug) << "Bin: " << i;
00236 for(UInt_t p = 0; p<nProf; p++) MSG("Chop",Msg::kDebug) << "\t" << Form("%6.0f",profiles[p][i]);
00237 MSG("Chop",Msg::kDebug) << endl;
00238 }
00239
00240 for(UInt_t p = 0; p<nProf; p++) {
00241 for(Int_t bin=cuts[icut]; bin<= cuts[icut]; bin++) {
00242 if(profiles[p][bin] < lowest_size) {
00243 lowest_size = profiles[p][bin];
00244 cuts[icut] = bin;
00245 cuts_type[icut] = p;
00246 }
00247 }
00248 }
00249
00250 MSG("Chop",Msg::kDebug) << " -> Cutting bin " << cuts[icut] << " on projection " << cuts_type[icut]
00251 << " lowbin: " << lowest_size << endl;
00252
00253 }
00254 }
00255
00256
00257
00258 cuts.push_back(numBins-1);
00259 cuts_type.push_back(0);
00260
00261 for(UInt_t icut=0; icut<cuts.size()-1; icut++) {
00262 DigitVector chop;
00263
00264 for(UInt_t idig = 0; idig < ndigits; idig++ ) {
00265
00266 float tdcbin = digit_tdc[idig]-tfirst;
00267 float dplane = digit_plane[idig];
00268 if(dplane>PlexPlaneId::LastPlaneNearCalor())
00269 dplane = PlexPlaneId::LastPlaneNearCalor();
00270 dplane -= 60.;
00271
00272 std::vector<int> proj(nProf);
00273 for(UInt_t p = 0; p<nProf; p++)
00274 proj[p] = TMath::Nint(tdcbin + profAngles[p]*dplane);
00275
00276
00277 if(proj[cuts_type[icut]] >= cuts[icut]) {
00278
00279
00280 if(proj[cuts_type[icut+1]] < cuts[icut+1] ) {
00281
00282
00283 chop.push_back(digits[idig]);
00284
00285 }
00286 }
00287 }
00288
00289 cxx.SetDataIn(&(chop));
00290 CandDigitListHandle chopHandle = CandDigitList::MakeCandidate(ah,cxx);
00291 chopHandle.SetName(Form("Chop %d",nchop++));
00292 chopList.AddDaughterLink(chopHandle);
00293
00294 MSG("Chop",Msg::kDebug) << "Creating chop. "
00295 << " Start: " << cuts[icut] << " Stop: " << cuts[icut+1]
00296 << " Digits: " << chop.size()
00297 << endl;
00298
00299 }
00300 }
00301
00302
00303 void AlgChopListMitre::Trace(const char * ) const
00304 {
00305 }
00306