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