00001
00002 #include "CondFormats/EcalObjects/interface/EcalChannelStatus.h"
00003 #include "CondTools/Ecal/interface/EcalChannelStatusXMLTranslator.h"
00004 #include "TROOT.h"
00005 #include "TH2F.h"
00006 #include "TCanvas.h"
00007 #include "TStyle.h"
00008 #include "TColor.h"
00009 #include "TLine.h"
00010 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00011 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00012
00013 #include "CondCore/Utilities/interface/PayLoadInspector.h"
00014 #include "CondCore/Utilities/interface/InspectorPythonWrapper.h"
00015
00016 #include <string>
00017 #include <fstream>
00018 #include <algorithm>
00019 #include <numeric>
00020 #include <iterator>
00021 #include <boost/ref.hpp>
00022 #include <boost/bind.hpp>
00023 #include <boost/function.hpp>
00024 #include <boost/iterator/transform_iterator.hpp>
00025
00026 namespace cond {
00027
00028
00029 namespace ecalcond {
00030
00031 typedef EcalChannelStatus Container;
00032 typedef Container::Items Items;
00033 typedef Container::value_type value_type;
00034
00035 enum How { singleChannel, bySuperModule, barrel, endcap, all};
00036
00037 int bad(Items const & cont) {
00038 return std::count_if(cont.begin(),cont.end(),
00039 boost::bind(std::greater<int>(),
00040 boost::bind(&value_type::getStatusCode,_1),0)
00041 );
00042 }
00043
00044
00045 void extractBarrel(Container const & cont, std::vector<int> const &, std::vector<float> & result) {
00046 result.resize(1);
00047 result[0] = bad(cont.barrelItems());
00048 }
00049 void extractEndcap(Container const & cont, std::vector<int> const &, std::vector<float> & result) {
00050 result.resize(1);
00051 result[0] = bad(cont.endcapItems());
00052 }
00053 void extractAll(Container const & cont, std::vector<int> const &, std::vector<float> & result) {
00054 result.resize(1);
00055 result[0] = bad(cont.barrelItems())+bad(cont.endcapItems());
00056 }
00057
00058 void extractSuperModules(Container const & cont, std::vector<int> const & which, std::vector<float> & result) {
00059
00060 }
00061
00062 void extractSingleChannel(Container const & cont, std::vector<int> const & which, std::vector<float> & result) {
00063 result.reserve(which.size());
00064 for (unsigned int i=0; i<which.size();i++) {
00065 result.push_back(cont[which[i]].getStatusCode());
00066 }
00067 }
00068
00069 typedef boost::function<void(Container const & cont, std::vector<int> const & which, std::vector<float> & result)> CondExtractor;
00070
00071 }
00072
00073 template<>
00074 struct ExtractWhat<ecalcond::Container> {
00075
00076 ecalcond::How m_how;
00077 std::vector<int> m_which;
00078
00079 ecalcond::How const & how() const { return m_how;}
00080 std::vector<int> const & which() const { return m_which;}
00081
00082 void set_how(ecalcond::How i) {m_how=i;}
00083 void set_which(std::vector<int> & i) { m_which.swap(i);}
00084 };
00085
00086
00087
00088
00089 template<>
00090 class ValueExtractor<ecalcond::Container>: public BaseValueExtractor<ecalcond::Container> {
00091 public:
00092
00093 static ecalcond::CondExtractor & extractor(ecalcond::How how) {
00094 static ecalcond::CondExtractor fun[5] = {
00095 ecalcond::CondExtractor(ecalcond::extractSingleChannel),
00096 ecalcond::CondExtractor(ecalcond::extractSuperModules),
00097 ecalcond::CondExtractor(ecalcond::extractBarrel),
00098 ecalcond::CondExtractor(ecalcond::extractEndcap),
00099 ecalcond::CondExtractor(ecalcond::extractAll)
00100 };
00101 return fun[how];
00102 }
00103
00104
00105 typedef ecalcond::Container Class;
00106 typedef ExtractWhat<Class> What;
00107 static What what() { return What();}
00108
00109 ValueExtractor(){}
00110 ValueExtractor(What const & what)
00111 : m_what(what)
00112 {
00113
00114
00115 }
00116
00117 void compute(Class const & it){
00118 std::vector<float> res;
00119 extractor(m_what.how())(it,m_what.which(),res);
00120 swap(res);
00121 }
00122
00123 private:
00124 What m_what;
00125
00126 };
00127
00128
00129 template<>
00130 std::string
00131 PayLoadInspector<EcalChannelStatus>::dump() const {
00132 std::stringstream ss;
00133 EcalCondHeader h;
00134 ss << EcalChannelStatusXMLTranslator::dumpXML(h,object());
00135 return ss.str();
00136
00137 }
00138
00139 std::string StCodeToStr(unsigned int const & statusCode){
00140 unsigned int bits_1to5, bits, mask;
00141 mask = 0x1F;
00142 bits_1to5 = mask & statusCode;
00143 std::stringstream ss;
00144 switch(bits_1to5){
00145 case 0: break;
00146 case 1: ss<< "["<< bits_1to5 << "]:" << "DAC settings problem, pedestal not in the design range, " << "Reco Action: standard reco."; break;
00147 case 2: ss<< "["<< bits_1to5 << "]:" << "channel with no laser, ok elsewhere; " << "Reco Action: standard reco."; break;
00148 case 3: ss<< "["<< bits_1to5 << "]:" << "noisy; " << "Reco Action: standard reco."; break;
00149 case 4: ss<< "["<< bits_1to5 << "]:" << "very noisy; " << "Reco Action: special reco (to be decided)."; break;
00150 case 5: ss<< "["<< bits_1to5 << "]: reserved for more categories of noisy channels."; break;
00151 case 6: ss<< "["<< bits_1to5 << "]: reserved for more categories of noisy channels."; break;
00152 case 7: ss<< "["<< bits_1to5 << "]: reserved for more categories of noisy channels."; break;
00153 case 8: ss<< "["<< bits_1to5 << "]:" << " channel at fixed gain 6 (or 6 and 1); " << "Reco Action: 3+5 or 3+1, special reco."; break;
00154 case 9: ss<< "["<< bits_1to5 << "]:" << " channel at fixed gain 1; " << "Reco Action: 3+5 or 3+1, special reco."; break;
00155 case 10: ss<< "["<< bits_1to5 << "]:" << " channel at fixed gain 0 (dead of type this); " << "Reco Action: recovery from neighbours."; break;
00156 case 11: ss<< "["<< bits_1to5 << "]:" << " non responding isolated channel (dead of type other); " << "Reco Action: recovery from neighbours."; break;
00157 case 12: ss<< "["<< bits_1to5 << "]:" << " channel and one or more neigbors not responding (e.g.: in a dead VFE 5x1 channel) " << "Reco Action: no recovery."; break;
00158 case 13: ss<< "["<< bits_1to5 << "]:" << " channel in TT with no data link, TP data ok; " << "Reco Action: recovery from TP data."; break;
00159 case 14: ss<< "["<< bits_1to5 << "]:" << " channel in TT with no data link and no TP data; " << "Reco Action: none."; break;
00160 default:
00161 ss<< "no such bits can be set!";
00162 }
00163 bits = 6;
00164
00165 mask = 1 << bits;
00166 if (statusCode & mask)
00167 ss << " bit["<< bits << "]:" << " HV good/not good;";
00168
00169 mask = 1 << ++bits;
00170 if (statusCode & mask)
00171 ss << " bit["<< bits << "]:" << " LV on/off;";
00172
00173 mask = 1 << ++bits;
00174 if (statusCode & mask)
00175 ss << " bit["<< bits << "]:" << " DAQ in/out;";
00176
00177 mask = 1 << ++bits;
00178 if (statusCode & mask)
00179 ss << " bit["<< bits << "]:" << " TP readout on/off;";
00180
00181 mask = 1 << ++bits;
00182 if (statusCode & mask)
00183 ss << " bit["<< bits << "]:" << " Trigger in/out;";
00184
00185 mask = 1 << ++bits;
00186 if (statusCode & mask)
00187 ss << " bit["<< bits << "]:" << " Temperature ok/not ok;";
00188
00189 mask = 1 << ++bits;
00190 if (statusCode & mask)
00191 ss << " bit["<< bits << "]:" << " Humidity ok/not;";
00192
00193
00194
00195 ss << std::endl;
00196 return ss.str();
00197 }
00198
00199 void setErr(unsigned int const & statusCode, std::vector< std::pair< std::string, unsigned int> > & vTotalWithErr){
00200 unsigned int bits_1to5, bits, mask;
00201 mask = 0x1F;
00202
00203 bits_1to5 = mask & statusCode;
00204 if ((bits_1to5 > 0) &&( bits_1to5 < 15)){
00205 vTotalWithErr[bits_1to5].second += 1;
00206 }
00207
00208 bits = 6;
00209
00210 mask = 1 << bits;
00211 if (statusCode & mask)
00212 vTotalWithErr[bits + 11].second += 1;
00213
00214 mask = 1 << ++bits;
00215 if (statusCode & mask)
00216 vTotalWithErr[bits + 11].second += 1;
00217
00218 mask = 1 << ++bits;
00219 if (statusCode & mask)
00220 vTotalWithErr[bits + 11].second += 1;
00221
00222 mask = 1 << ++bits;
00223 if (statusCode & mask)
00224 vTotalWithErr[bits + 11].second += 1;
00225
00226 mask = 1 << ++bits;
00227 if (statusCode & mask)
00228 vTotalWithErr[bits + 11].second += 1;
00229
00230 mask = 1 << ++bits;
00231 if (statusCode & mask)
00232 vTotalWithErr[bits + 11].second += 1;
00233
00234 mask = 1 << ++bits;
00235 if (statusCode & mask)
00236 vTotalWithErr[bits + 11].second += 1;
00237 }
00238
00239 std::string getTotalErrors(const std::vector<EcalChannelStatusCode> & vItems){
00240 unsigned int stcode = 0, index = 0, totalErrorCodes = 22;
00241 std::stringstream ss;
00242 std::vector< std::pair< std::string, unsigned int > > vTotalWithErr(totalErrorCodes);
00243
00244
00245
00246 index = 0;
00247 ss.str(""); ss << " No errors. "; vTotalWithErr[index].first = ss.str(); ++index;
00248 ss.str(""); ss << "["<< index << "]:" << "DAC settings problem, pedestal not in the design range, " << "Reco Action: standard reco."; vTotalWithErr[index].first = ss.str(); ++index;
00249 ss.str(""); ss << "["<< index << "]:" << "channel with no laser, ok elsewhere; " << "Reco Action: standard reco."; vTotalWithErr[index].first = ss.str(); ++index;
00250 ss.str(""); ss << "["<< index << "]:" << "noisy; " << "Reco Action: standard reco."; vTotalWithErr[index].first = ss.str(); ++index;
00251 ss.str(""); ss << "["<< index << "]:" << "very noisy; " << "Reco Action: special reco (to be decided)."; vTotalWithErr[index].first = ss.str(); ++index;
00252 ss.str(""); ss << "["<< index << "]: reserved for more categories of noisy channels."; vTotalWithErr[index].first = ss.str(); ++index;
00253 ss.str(""); ss << "["<< index << "]: reserved for more categories of noisy channels."; vTotalWithErr[index].first = ss.str(); ++index;
00254 ss.str(""); ss << "["<< index << "]: reserved for more categories of noisy channels."; vTotalWithErr[index].first = ss.str(); ++index;
00255 ss.str(""); ss << "["<< index << "]:" << " channel at fixed gain 6 (or 6 and 1); " << "Reco Action: 3+5 or 3+1, special reco."; vTotalWithErr[index].first = ss.str(); ++index;
00256 ss.str(""); ss << "["<< index << "]:" << " channel at fixed gain 1; " << "Reco Action: 3+5 or 3+1, special reco."; vTotalWithErr[index].first = ss.str(); ++index;
00257 ss.str(""); ss << "["<< index << "]:" << " channel at fixed gain 0 (dead of type this); " << "Reco Action: recovery from neighbours."; vTotalWithErr[index].first = ss.str(); ++index;
00258 ss.str(""); ss << "["<< index << "]:" << " non responding isolated channel (dead of type other); " << "Reco Action: recovery from neighbours."; vTotalWithErr[index].first = ss.str(); ++index;
00259 ss.str(""); ss << "["<< index << "]:" << " channel and one or more neigbors not responding (e.g.: in a dead VFE 5x1 channel) " << "Reco Action: no recovery."; vTotalWithErr[index].first = ss.str(); ++index;
00260 ss.str(""); ss << "["<< index << "]:" << " channel in TT with no data link, TP data ok; " << "Reco Action: recovery from TP data."; vTotalWithErr[index].first = ss.str(); ++index;
00261 ss.str(""); ss << "["<< index << "]:" << " channel in TT with no data link and no TP data; " << "Reco Action: none."; vTotalWithErr[index].first = ss.str(); ++index;
00262
00263 unsigned int bits = 6;
00264 ss.str(""); ss << " bit["<< bits++ << "]:" << " HV good/not good;"; vTotalWithErr[index].first = ss.str(); ++index;
00265 ss.str(""); ss << " bit["<< bits++ << "]:" << " LV on/off;"; vTotalWithErr[index].first = ss.str(); ++index;
00266 ss.str(""); ss << " bit["<< bits++ << "]:" << " DAQ in/out;"; vTotalWithErr[index].first = ss.str(); ++index;
00267 ss.str(""); ss << " bit["<< bits++ << "]:" << " TP readout on/off;"; vTotalWithErr[index].first = ss.str(); ++index;
00268 ss.str(""); ss << " bit["<< bits++ << "]:" << " Trigger in/out;"; vTotalWithErr[index].first = ss.str(); ++index;
00269 ss.str(""); ss << " bit["<< bits++ << "]:" << " Temperature ok/not ok;"; vTotalWithErr[index].first = ss.str(); ++index;
00270 ss.str(""); ss << " bit["<< bits++ << "]:" << " Humidity ok/not;"; vTotalWithErr[index].first = ss.str(); ++index;
00271
00272
00273 ss.str("");
00274
00275 for (std::vector<EcalChannelStatusCode>::const_iterator vIter = vItems.begin(); vIter != vItems.end(); ++vIter){
00276 stcode = vIter->getStatusCode();
00277 if (stcode !=0){
00278 setErr(stcode, vTotalWithErr);
00279 }
00280 }
00281
00282 unsigned int i = 0;
00283 for (std::vector< std::pair< std::string, unsigned int > >::const_iterator iTotalErr = vTotalWithErr.begin(); iTotalErr != vTotalWithErr.end(); ++iTotalErr){
00284 if (iTotalErr->second != 0)
00285 ss << "Total:" << iTotalErr->second << " Error:" << iTotalErr->first << std::endl;
00286 ++i;
00287 }
00288 return ss.str();
00289 }
00290
00291 template<>
00292 std::string PayLoadInspector<EcalChannelStatus>::summary() const {
00293 const std::vector<EcalChannelStatusCode> barrelItems = object().barrelItems();
00294 const std::vector<EcalChannelStatusCode> endcapItems = object().endcapItems();
00295 std::stringstream ss;
00296
00297 ss << std::endl << "------Barrel Items: " << std::endl;
00298 ss << "---Total: " << barrelItems.size() << std::endl;
00299 ss << "---With errors: " << ecalcond::bad(barrelItems) << std::endl;
00300 ss << getTotalErrors(barrelItems);
00301
00302 ss << std::endl << "------Endcap Items: " << std::endl;
00303 ss << "---Total: " << endcapItems.size() << std::endl;
00304 ss << "---With errors: " << ecalcond::bad(endcapItems) << std::endl;
00305 ss << getTotalErrors(endcapItems);
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 return ss.str();
00342 }
00343
00344
00345 template<>
00346 std::string PayLoadInspector<EcalChannelStatus>::plot(std::string const & filename,
00347 std::string const &,
00348 std::vector<int> const&,
00349 std::vector<float> const& ) const {
00350
00351 gStyle->SetPalette(1);
00352
00353 const Int_t NRGBs = 5;
00354 const Int_t NCont = 255;
00355
00356 Double_t stops[NRGBs] = { 0.00, 0.34, 0.61, 0.84, 1.00 };
00357 Double_t red[NRGBs] = { 0.00, 0.00, 0.87, 1.00, 0.51 };
00358 Double_t green[NRGBs] = { 0.00, 0.81, 1.00, 0.20, 0.00 };
00359 Double_t blue[NRGBs] = { 0.51, 1.00, 0.12, 0.00, 0.00 };
00360 TColor::CreateGradientColorTable(NRGBs, stops, red, green, blue, NCont);
00361 gStyle->SetNumberContours(NCont);
00362
00363 TCanvas canvas("CC map","CC map",800,800);
00364 TPad* padb = new TPad("padb","padb", 0., 0.55, 1., 1.);
00365 padb->Draw();
00366 TPad* padem = new TPad("padem","padem", 0., 0., 0.45, 0.45);
00367 padem->Draw();
00368 TPad* padep = new TPad("padep","padep", 0.55, 0., 1., 0.45);
00369 padep->Draw();
00370
00371 const int kSides = 2;
00372 const int kBarlRings = EBDetId::MAX_IETA;
00373 const int kBarlWedges = EBDetId::MAX_IPHI;
00374 const int kEndcWedgesX = EEDetId::IX_MAX;
00375 const int kEndcWedgesY = EEDetId::IY_MAX;
00376
00377 TH2F* barrel = new TH2F("EB","EB Channel Status",360,0,360, 171, -85,86);
00378 TH2F* endc_p = new TH2F("EE+","EE+ Channel Status",100,1,101,100,1,101);
00379 TH2F* endc_m = new TH2F("EE-","EE- Channel Status",100,1,101,100,1,101);
00380
00381 for (int sign=0; sign < kSides; sign++) {
00382 int thesign = sign==1 ? 1:-1;
00383
00384 for (int ieta=0; ieta<kBarlRings; ieta++) {
00385 for (int iphi=0; iphi<kBarlWedges; iphi++) {
00386 EBDetId id((ieta+1)*thesign, iphi+1);
00387 barrel->Fill(iphi, ieta*thesign + thesign, object()[id.rawId()].getStatusCode());
00388
00389
00390 }
00391 }
00392
00393 for (int ix=0; ix<kEndcWedgesX; ix++) {
00394 for (int iy=0; iy<kEndcWedgesY; iy++) {
00395 if (! EEDetId::validDetId(ix+1,iy+1,thesign)) continue;
00396 EEDetId id(ix+1,iy+1,thesign);
00397 if (thesign==1) {
00398 endc_p->Fill(ix+1,iy+1,object()[id.rawId()].getStatusCode());
00399 }
00400 else{
00401 endc_m->Fill(ix+1,iy+1,object()[id.rawId()].getStatusCode());
00402 }
00403 }
00404 }
00405 }
00406
00407 TLine* l = new TLine(0., 0., 0., 0.);
00408 l->SetLineWidth(1);
00409 padb->cd();
00410 barrel->SetStats(0);
00411 barrel->SetMaximum(14);
00412 barrel->SetMinimum(0);
00413 barrel->Draw("colz");
00414 for(int i = 0; i <17; i++) {
00415 Double_t x = 20.+ (i *20);
00416 l = new TLine(x,-85.,x,86.);
00417 l->Draw();
00418 }
00419 l = new TLine(0.,0.,360.,0.);
00420 l->Draw();
00421 int ixSectorsEE[202] = {
00422 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 56, 56, 46, 46, 44, 44, 43, 43, 42, 42,
00423 41, 41, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 46, 46, 56, 56, 58, 58, 59, 59,
00424 60, 60, 61, 61, 62, 62, 0,101,101, 98, 98, 96, 96, 93, 93, 88, 88, 86, 86, 81,
00425 81, 76, 76, 66, 66, 61, 61, 41, 41, 36, 36, 26, 26, 21, 21, 16, 16, 14, 14, 9,
00426 9, 6, 6, 4, 4, 1, 1, 4, 4, 6, 6, 9, 9, 14, 14, 16, 16, 21, 21, 26,
00427 26, 36, 36, 41, 41, 61, 61, 66, 66, 76, 76, 81, 81, 86, 86, 88, 88, 93, 93, 96,
00428 96, 98, 98,101,101, 0, 62, 66, 66, 71, 71, 81, 81, 91, 91, 93, 0, 62, 66, 66,
00429 91, 91, 98, 0, 58, 61, 61, 66, 66, 71, 71, 76, 76, 81, 81, 0, 51, 51, 0, 44,
00430 41, 41, 36, 36, 31, 31, 26, 26, 21, 21, 0, 40, 36, 36, 11, 11, 4, 0, 40, 36,
00431 36, 31, 31, 21, 21, 11, 11, 9, 0, 46, 46, 41, 41, 36, 36, 0, 56, 56, 61, 61, 66, 66};
00432
00433 int iySectorsEE[202] = {
00434 51, 56, 56, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 61, 61, 60, 60, 59, 59, 58,
00435 58, 56, 56, 46, 46, 44, 44, 43, 43, 42, 42, 41, 41, 40, 40, 41, 41, 42, 42, 43,
00436 43, 44, 44, 46, 46, 51, 0, 51, 61, 61, 66, 66, 76, 76, 81, 81, 86, 86, 88, 88,
00437 93, 93, 96, 96, 98, 98,101,101, 98, 98, 96, 96, 93, 93, 88, 88, 86, 86, 81, 81,
00438 76, 76, 66, 66, 61, 61, 41, 41, 36, 36, 26, 26, 21, 21, 16, 16, 14, 14, 9, 9,
00439 6, 6, 4, 4, 1, 1, 4, 4, 6, 6, 9, 9, 14, 14, 16, 16, 21, 21, 26, 26,
00440 36, 36, 41, 41, 51, 0, 46, 46, 41, 41, 36, 36, 31, 31, 26, 26, 0, 51, 51, 56,
00441 56, 61, 61, 0, 61, 61, 66, 66, 71, 71, 76, 76, 86, 86, 88, 0, 62,101, 0, 61,
00442 61, 66, 66, 71, 71, 76, 76, 86, 86, 88, 0, 51, 51, 56, 56, 61, 61, 0, 46, 46,
00443 41, 41, 36, 36, 31, 31, 26, 26, 0, 40, 31, 31, 16, 16, 6, 0, 40, 31, 31, 16, 16, 6};
00444
00445 padem->cd();
00446 endc_m->SetStats(0);
00447 endc_m->SetMaximum(14);
00448 endc_m->SetMinimum(0);
00449 endc_m->Draw("colz");
00450 for ( int i=0; i<201; i=i+1) {
00451 if ( (ixSectorsEE[i]!=0 || iySectorsEE[i]!=0) &&
00452 (ixSectorsEE[i+1]!=0 || iySectorsEE[i+1]!=0) ) {
00453 l->DrawLine(ixSectorsEE[i], iySectorsEE[i],
00454 ixSectorsEE[i+1], iySectorsEE[i+1]);
00455 }
00456 }
00457 padep->cd();
00458 endc_p->SetStats(0);
00459 endc_p->SetMaximum(14);
00460 endc_p->SetMinimum(0);
00461 endc_p->Draw("colz");
00462 for ( int i=0; i<201; i=i+1) {
00463 if ( (ixSectorsEE[i]!=0 || iySectorsEE[i]!=0) &&
00464 (ixSectorsEE[i+1]!=0 || iySectorsEE[i+1]!=0) ) {
00465 l->DrawLine(ixSectorsEE[i], iySectorsEE[i],
00466 ixSectorsEE[i+1], iySectorsEE[i+1]);
00467 }
00468 }
00469 canvas.SaveAs(filename.c_str());
00470 return filename;
00471 }
00472 }
00473
00474 namespace condPython {
00475 template<>
00476 void defineWhat<cond::ecalcond::Container>() {
00477 using namespace boost::python;
00478 enum_<cond::ecalcond::How>("How")
00479 .value("singleChannel",cond::ecalcond::singleChannel)
00480 .value("bySuperModule",cond::ecalcond::bySuperModule)
00481 .value("barrel",cond::ecalcond::barrel)
00482 .value("endcap",cond::ecalcond::endcap)
00483 .value("all",cond::ecalcond::all)
00484 ;
00485
00486 typedef cond::ExtractWhat<cond::ecalcond::Container> What;
00487 class_<What>("What",init<>())
00488 .def("set_how",&What::set_how)
00489 .def("set_which",&What::set_which)
00490 .def("how",&What::how, return_value_policy<copy_const_reference>())
00491 .def("which",&What::which, return_value_policy<copy_const_reference>())
00492 ;
00493 }
00494 }
00495
00496 PYTHON_WRAPPER(EcalChannelStatus,EcalChannelStatus);