/search.css" rel="stylesheet" type="text/css"/> /search.js">
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

DybChannelQualitySvc.cc
Go to the documentation of this file.
00001 #include "DybChannelQualitySvc.h"
00002 #include "HardCodedNoisyChannels.h"
00003 #include "ChannelPacked.h"
00004 
00005 #include "DatabaseInterface/DbiResultPtr.h"
00006 #include "Conventions/Detectors.h"
00007 #include "Conventions/Electronics.h"
00008 
00009 #include "genDbi/GAdWpHvMap.h"
00010 #include "genDbi/GAdWpHvSetting.h"
00011 #include "genDbi/GAdWpHvToFee.h"
00012 #include "genDbi/GDcsAdWpHv.h"
00013 
00014 
00015 /* From Gassing Li, re channel quality status table:
00016 
00017   The final strategy we adopted for the GDqChannelPacked table, for
00018   which the new channel quality service would query, is to pack the
00019   192 status bits ordered by their corresponding FeeChannelId into 7
00020   integers and saved in one payload record. Only the lower 31 bits for
00021   each integer are used for packing status. The packing details are in
00022   the pack method at
00023  
00024   http://dayawane.ihep.ac.cn/tracs/dybsvn/browser/dybgaudi/trunk/Database/Scraper/python/Scraper/dq/CQPacker.py
00025 
00026   see also
00027 
00028   http://dayabay.ihep.ac.cn/DocDB/0090/009090/001/CQ_Service_Status_20130710.pdf
00029 
00030   Update: this is augmented with the ability to set bad channels via a
00031   configurable list.  Items in this list will override the
00032   GdqChannelPacked table.
00033 
00034 */
00035 #include "genDbi/GDqChannelPacked.h"
00036 // needed to determine ordering of DqChannelPacked bits
00037 #include "genDbi/GCableMap.h"
00038 
00039 #include <string>
00040 #include <cmath>
00041 
00042 #include <iostream>
00043 #include <sstream>
00044 using namespace std;
00045 
00046 DybChanQualCache::DybChanQualCache(const ServiceMode& sm, bool usehv, bool usenoisy)
00047     : m_timelessSM(Context(sm.context().GetSite(), 
00048                            sm.context().GetSimFlag(),
00049                                TimeStamp(0,0),
00050                                sm.context().GetDetId()),
00051                        sm.task())
00052     , m_hvlocKey(0)
00053     , m_hvfeeKey(0)
00054     , m_hvgetKey(0)
00055     , m_hvsetKey(0)
00056     , m_dqcpKey(0)
00057     , m_cmapKey(0)
00058     , m_useHV(usehv)
00059     , m_useNoisy(usenoisy)
00060 {
00061     this->update(sm.context().GetTimeStamp());
00062 }
00063 
00064 template<class GTable> 
00065 bool update_table(const std::string& name,
00066                   const Context& ctx, int task,
00067                   DbiResultKey *&kept_key,
00068                   DbiResultPtr<GTable> *&resptr)
00069 {
00070     resptr =  new DbiResultPtr<GTable>(name.c_str(), ctx, ctx.GetDetId(), task);
00071     const DbiResultKey* key= resptr->GetKey(); 
00072 
00073     if (key && kept_key) {
00074         if (key->IsEqualTo(kept_key)) {
00075             return false;
00076         }
00077         delete kept_key;
00078         kept_key = new DbiResultKey(key);
00079         return true;
00080     }
00081 
00082     if (!key && !kept_key) {
00083         return false;
00084     }
00085 
00086 
00087     if (key) {
00088         kept_key = new DbiResultKey(key);
00089         return true;
00090     }
00091 
00092     delete kept_key;
00093     kept_key = 0;
00094     return true;
00095 }
00096                                     
00097 
00098 bool DybChanQualCache::empty()
00099 {
00100     bool full = m_dqcp.size()>0 && m_chlist.size()>0;
00101     if (m_useHV) {
00102         full = full && m_hvset.size()>0 && m_hvget.size()>0;
00103     }
00104     return !full;
00105 }
00106 
00107 void DybChanQualCache::check_hvchid(DayaBay::HvChannelId hvch, const std::string& who)
00108 {
00109     if (!hvch.bogus()) { return; }
00110 
00111     stringstream ss;
00112     ss << " bogus HvChannelId: " << hvch.asString();
00113     throw GaudiException(ss.str().c_str(), who, StatusCode::FAILURE);
00114 }
00115 
00116 bool DybChanQualCache::update_hvloc(Context& ctx)
00117 {
00118     DbiResultPtr<GAdWpHvMap>* res = 0;
00119     bool updated = update_table<GAdWpHvMap>("AdWpHvMap",
00120                                             ctx, m_timelessSM.task(), m_hvlocKey, res);
00121     if (updated) { 
00122         m_loc2hv.clear();
00123         unsigned int ind, nrows = res->GetNumRows();
00124         //cerr << "Updating from AdWpHvMap with " << nrows << " rows @ " << ctx.AsString("E") << endl;
00125         if (!nrows) {
00126             throw GaudiException("DybChannelQualitySvc no AdWpHvMap entries",
00127                                  "DybChanQualCache",StatusCode::FAILURE);
00128         }
00129 
00130         for (ind=0; ind < nrows; ++ind) {
00131             const GAdWpHvMap* row = res->GetRowByIndex(ind);
00132             DayaBay::HvChannelId hvch = row->GetHvChannelId();
00133             check_hvchid(hvch,"AdWpHvMap");
00134             std::string loc = row->GetLocationId();
00135             m_loc2hv[loc] = hvch;
00136         }
00137     }
00138 
00139     delete res;
00140     return updated;
00141 }
00142 
00143 bool DybChanQualCache::update_hvfee(Context& ctx)
00144 {
00145     DbiResultPtr<GAdWpHvToFee>* res = 0;
00146     bool updated = update_table<GAdWpHvToFee>("AdWpHvToFee",
00147                                               ctx, m_timelessSM.task(), m_hvfeeKey, res);
00148     if (updated) {
00149         m_hv2fee.clear();
00150         unsigned int ind, nrows = res->GetNumRows();
00151         //cerr << "Updating from AdWpHvToFee with " << nrows << " rows @ " << ctx.AsString("E") << endl;
00152         if (!nrows) {
00153             throw GaudiException("DybChannelQualitySvc no AdWpHvToFee entries",
00154                                  "DybChanQualCache",StatusCode::FAILURE);
00155         }
00156 
00157         for (ind=0; ind < nrows; ++ind) {
00158             const GAdWpHvToFee* row = res->GetRowByIndex(ind);
00159             DayaBay::HvChannelId hvch = row->GetHvChannelId();
00160             check_hvchid(hvch,"AdWpHvToFee");
00161             DayaBay::FeeChannelId chid = row->GetFeeChannelId();
00162             m_hv2fee[hvch] = chid;
00163         }
00164     }
00165     delete res;
00166     return updated;
00167 }
00168 
00169 DayaBay::FeeChannelId DybChanQualCache::hv2fee(DayaBay::HvChannelId hvch)
00170 {
00171     DayaBay::FeeChannelId feech = m_hv2fee[hvch];
00172     if (feech.bogus()) {
00173         stringstream ss;
00174         // ss << "Got bogus FeeChannelId out of " << m_hv2fee.size() 
00175         //    << " from HvChannelId=" << hvch
00176         //    << ", crate=" << hvch.crate()
00177         //    << ", board=" << hvch.slot()
00178         //    << ", channel=" << hvch.channel();
00179         throw GaudiException(ss.str().c_str(),
00180                              "DybChanQualCache",StatusCode::FAILURE);
00181     }
00182     return feech;
00183 }
00184 
00185 
00186 bool DybChanQualCache::update_hvset(Context& ctx, bool force)
00187 {
00188     DbiResultPtr<GAdWpHvSetting>* res = 0;
00189     bool updated = update_table<GAdWpHvSetting>("AdWpHvSetting", 
00190                                                 ctx, m_timelessSM.task(), m_hvsetKey, res);
00191     if (!updated) { updated = force; }
00192     if (updated) {
00193         m_hvset.clear();
00194         unsigned int ind, nrows = res->GetNumRows();
00195         //cerr << "Updating from AdWpHvToSetting with " << nrows << " rows @ " << ctx.AsString("E") << endl;
00196         if (!nrows) {
00197             throw GaudiException("DybChannelQualitySvc no AdWpHvSetting entries",
00198                                  "DybChanQualCache",StatusCode::FAILURE);
00199         }
00200 
00201         for (ind=0; ind < nrows; ++ind) {
00202             const GAdWpHvSetting* row = res->GetRowByIndex(ind);
00203             DayaBay::HvChannelId hvch = row->GetHvChannelId();
00204             check_hvchid(hvch,"AdWpHvSetting");
00205             DayaBay::FeeChannelId feech = hv2fee(hvch);
00206             m_hvset[feech] = row->GetHvSetting();
00207         }
00208     }
00209     delete res;
00210     return updated;
00211 }
00212 
00213 bool DybChanQualCache::update_hvget(Context& ctx, bool force)
00214 {
00215     DbiResultPtr<GDcsAdWpHv>* res = 0;
00216     bool updated = update_table<GDcsAdWpHv>("DcsAdWpHv", 
00217                                             ctx, m_timelessSM.task(), m_hvgetKey, res);
00218     if (!updated) { updated = force; }
00219     if (updated) {
00220         m_hvget.clear();
00221         unsigned int ind, nrows = res->GetNumRows();
00222         //cerr << "Updating from DcsAdWpHv with " << nrows << " rows @ " << ctx.AsString("E") << endl;
00223         if (!nrows) {
00224             throw GaudiException("DybChannelQualitySvc no DcsAdWpHv entries",
00225                                  "DybChanQualCache",StatusCode::FAILURE);
00226         }
00227 
00228         for (ind=0; ind < nrows; ++ind) {
00229             const GDcsAdWpHv* row = res->GetRowByIndex(ind);
00230             std::string loc = row->GetLocationId();
00231             DayaBay::HvChannelId hvch = m_loc2hv[loc];
00232             check_hvchid(hvch,loc);
00233             DayaBay::FeeChannelId feech = hv2fee(hvch);
00234             m_hvget[feech] = row->GetVoltage();
00235         }
00236     }
00237     delete res;
00238     return updated;
00239 }
00240 
00241 bool DybChanQualCache::update_cmap(Context& ctx)
00242 {
00243     DbiResultPtr<GCableMap>* res = 0;
00244     bool updated = update_table<GCableMap>("CableMap",
00245                                            ctx, m_timelessSM.task(), m_cmapKey, res);
00246     if (updated) {
00247         m_chlist.clear();
00248         unsigned int ind=0, nrows = res->GetNumRows();
00249         if (!nrows) {
00250             throw GaudiException("DybChannelQualitySvc no CableMap entries",
00251                                  "DybChanQualCache",StatusCode::FAILURE);
00252         }
00253         
00254         for (ind=0; ind<nrows; ++ind) {
00255             const GCableMap* row = res->GetRowByIndex(ind);
00256             DayaBay::AdPmtSensor pmt(row->GetSensorId().fullPackedData());
00257             if (! pmt.is8inch()) {
00258                 continue;
00259             }
00260             m_chlist.push_back(row->GetChannelId().fullPackedData());
00261         }
00262         m_chlist.sort();
00263     }
00264     delete res;
00265     return updated;
00266 }
00267 bool DybChanQualCache::update_dqcp(Context& ctx)
00268 {
00269     DbiResultPtr<GDqChannelPacked>* res = 0;
00270     bool updated = update_table<GDqChannelPacked>("DqChannelPacked",
00271                                                   ctx, m_timelessSM.task(), m_dqcpKey, res);
00272     if (updated) {
00273         unsigned int nrows = res->GetNumRows();
00274         if (!nrows) {
00275             throw GaudiException("DybChannelQualitySvc no DqChannelPacked entries",
00276                                  "DybChanQualCache",StatusCode::FAILURE);
00277         }
00278         
00279         if (nrows > 1) {
00280             cerr << "Got ignoring additional ("<<nrows-1<<") DqChannelPacked results for " << ctx.AsString() << endl;
00281         }
00282         const GDqChannelPacked* row = res->GetRowByIndex(0);
00283         ChannelPacked::CQpacked packed;
00284         packed.push_back(row->GetMask0());
00285         packed.push_back(row->GetMask1());
00286         packed.push_back(row->GetMask2());
00287         packed.push_back(row->GetMask3());
00288         packed.push_back(row->GetMask4());
00289         packed.push_back(row->GetMask5());
00290         packed.push_back(row->GetMask6());
00291         
00292         ChannelPacked::CQbits channel_quality = ChannelPacked::unpack(packed);
00293 
00294         ChList_t::iterator it, done = m_chlist.end();
00295         int cqind = 0;
00296         m_dqcp.clear();
00297         for (it=m_chlist.begin(); it != done; ++it, ++cqind) {
00298             DayaBay::FeeChannelId chid(*it);
00299             m_dqcp[chid] = channel_quality[cqind]; // whew
00300         }
00301     }
00302     delete res;
00303     return updated;
00304     
00305 }
00306 
00307 
00308 // FIXME: see where called below, for now, always update
00309 bool DybChanQualCache::update_noise(Context& ctx, bool /*force*/)
00310 {
00311     //cerr << "update_noise("<<ctx.AsString("E")<<") clearing " << m_noise.size() << " channels" << endl;
00312     m_noise.clear();
00313 
00314     for (int ind=0; Dyb::noisy_channels[ind].channel.fullPackedData(); ++ind) {
00315         Dyb::NoisyChannel& nc = Dyb::noisy_channels[ind];
00316         //cerr << "update_noise() checking: " << nc.channel << " from " << nc.start.AsString("E") << " to " << nc.stop.AsString("E") << endl;
00317 
00318         if (! nc.covered(ctx)) { continue; }
00319         //cerr << "Caching based on " << ctx.AsString("E") << endl;
00320         m_noise[nc.channel] = nc.noise;
00321     }
00322 
00323     //cerr << "update_noise(): cached " << m_noise.size() << " noisy channels" << endl;
00324     return true;
00325 }
00326 
00327 // Maybe update cache based on a low level DBI update.  Return
00328 // true if an update happened
00329 bool DybChanQualCache::update(const TimeStamp& ts)
00330 {
00331     // Progressively check more expensively if this timestamp is "new"
00332 
00333     if (ts.GetSec() == m_lastTS.GetSec() && ts.GetNanoSec() == m_lastTS.GetNanoSec()) {
00334         //cerr << "Cache clean on timestamp value: " << ts.AsString() << endl;
00335         return false;
00336     }
00337     m_lastTS = ts;
00338     
00339     Context ctx = m_timelessSM.context();
00340     ctx.SetTimeStamp(ts);
00341 
00342     //cerr << "Checking cache for " << ctx.AsString("E") << endl;
00343 
00344     bool updated_hv = false;
00345     if (m_useHV) {
00346         bool updated_hvloc = update_hvloc(ctx);
00347         bool updated_hvfee = update_hvfee(ctx);
00348         bool updated_hvset = update_hvset(ctx, updated_hvfee);
00349         bool updated_hvget = update_hvget(ctx, updated_hvfee|updated_hvloc);
00350         updated_hv = updated_hvset || updated_hvget;
00351     }
00352 
00353     /*bool updated_cmap =*/ update_cmap(ctx);
00354     bool updated_dqcp = update_dqcp(ctx);
00355 
00356     if (m_useNoisy) {
00357         update_noise(ctx, true);
00358     }
00359 
00360     return updated_hv || updated_dqcp;
00361 }
00362 
00363 
00364 bool DybChanQualCache::covers(const TimeStamp& start, const TimeStamp& stop)
00365 {
00366     return start <= m_lastTS && m_lastTS < stop;
00367 }
00368 
00369 
00370 //
00371 // DybChannelQuality view (with ownership) into the cache
00372 //
00373 
00374 DybChannelQuality::DybChannelQuality(DybChanQualCache* cdc, std::vector<Dyb::ChannelOverride>& chor,
00375                                      float delta_hv,
00376                                      bool usehv, bool usenoisy)
00377     : m_cdc(cdc)
00378     , m_deltaHV(delta_hv)
00379     , m_useHV(usehv)
00380     , m_useNoisy(usenoisy)
00381     , m_chor(chor)
00382 {
00383     
00384 }
00385 
00386 DybChannelQuality::~DybChannelQuality()
00387 {
00388     delete m_cdc;
00389     m_cdc = 0;
00390 }
00391 
00392 bool DybChannelQuality::good(DayaBay::FeeChannelId chid) const
00393 {
00394     size_t nchors = m_chor.size();
00395     if (nchors) {
00396         //cerr << "Looking for " << chid.asString() << " out of  " << nchors << endl;
00397         for (size_t ind=0; ind < nchors; ++ind) {
00398             const Dyb::ChannelOverride& chor = m_chor[ind];
00399             if (chor.channel != chid) {
00400                 //cerr << "\twrong channel != " << chor.channel.asString() << endl;
00401                 continue;
00402             }
00403             if (!m_cdc->covers(chor.start, chor.stop)) {
00404                 //cerr << "\tdoes not cover " << chor.start.AsString() << " -- " << chor.stop.AsString() << endl;
00405                 continue;
00406             }
00407             //cerr << "\tgot it, qual = " << chor.good << endl;
00408             return chor.good;
00409         }
00410     }
00411     else {
00412         //cerr << "No overrides " << chid.asString() << endl;
00413     }
00414 
00415     if (m_useHV) {
00416         float requested = hvRequested(chid);
00417         if (requested < m_deltaHV) {
00418             return false;
00419         }
00420 
00421         float measured = hvMeasured(chid);
00422         if (measured < m_deltaHV) {
00423             return false;
00424         }
00425 
00426         if (fabs(requested-measured) > m_deltaHV) {
00427             return false;
00428         }
00429     }
00430 
00431     if (m_useNoisy) {
00432         if (noise(chid) > Dyb::noisy_channel_cut) {
00433             return false;
00434         }
00435     }
00436 
00437     // Return bad if channel is bad or not found (-1).  If not found
00438     // something is really wrong!  We should really assert that it's
00439     // not negative but the desired strategy from the calib group is
00440     // to fail towards acceptance.  So the impossible is merely
00441     // considered bad here.
00442     if (goodDqCp(chid) <= 0) {
00443         return false;
00444     }
00445 
00446     // Hurrah!
00447     return true;
00448 }
00449 
00450 int DybChannelQuality::goodDqCp(DayaBay::FeeChannelId chid) const
00451 {
00452     DybChanQualCache::DqCpMap_t& dqcp = m_cdc->channel_quality();
00453     DybChanQualCache::DqCpMap_t::iterator it = dqcp.find(chid);
00454     if (it == dqcp.end()) { return -1; }
00455     return it->second;
00456 }
00457 
00458 float DybChannelQuality::hvRequested(DayaBay::FeeChannelId chid) const
00459 {
00460     return m_cdc->setted_hv()[chid];
00461 }
00462 
00463 float DybChannelQuality::hvMeasured(DayaBay::FeeChannelId chid) const
00464 {
00465     return m_cdc->getted_hv()[chid];
00466 }
00467 
00468 float DybChannelQuality::noise(DayaBay::FeeChannelId chid) const
00469 {
00470     DybChanQualCache::HvValMap_t& n = m_cdc->noise();
00471         
00472     DybChanQualCache::HvValMap_t::iterator it = n.find(chid);
00473     if (it == n.end()) { return 0.0; } // no noise is good noise
00474     return it->second;
00475 }
00476 
00477 
00478 
00480 IChannelQuality::ChannelSet_t DybChannelQuality::channels() const
00481 {
00482     IChannelQuality::ChannelSet_t ret;
00483 
00484     DybChanQualCache::DqCpMap_t& cqmap = m_cdc->channel_quality();
00485     DybChanQualCache::DqCpMap_t::iterator it, done = cqmap.end();
00486 
00487     for (it=cqmap.begin(); it != done; ++it) {
00488         ret.push_back(it->first);
00489     }
00490     return ret;
00491 }
00492 
00493 //
00494 // DybChannelQualitySvc
00495 //
00496 
00497 DybChannelQualitySvc::DybChannelQualitySvc(const std::string& name, ISvcLocator *svc)
00498     : Service(name,svc)
00499     , m_lastSM()
00500 {
00501     declareProperty("UseHV", m_useHV=false,"Consider HV tables");
00502     declareProperty("UseNoisy", m_useNoisy=false,"Consider hard coded noisy channels");
00503 
00504     declareProperty("ChannelOverride", m_chor_strings,
00505                     "List of channel override strings.");
00506 
00507 }
00508 
00509 
00510 DybChannelQualitySvc::~DybChannelQualitySvc()
00511 {
00512 }
00513 
00514 StatusCode DybChannelQualitySvc::initialize()
00515 {
00516     StatusCode sc = this->Service::initialize();
00517     if( sc.isFailure() ) return sc;
00518 
00519     size_t nchor = m_chor_strings.size();
00520     //cerr << "DybChannelQualitySvc::initialize() with #chor = " << nchor << endl;
00521     for (size_t ind=0; ind<nchor; ++ind) {
00522         string chor = m_chor_strings[ind];
00523         m_chor.push_back(Dyb::ChannelOverride(chor));
00524         //cerr << "\tchor: " << chor << endl;
00525     }
00526     return StatusCode::SUCCESS;
00527 }
00528 
00529 const IChannelQuality* DybChannelQualitySvc::get(const ServiceMode& sm)
00530 {
00531     ServiceMode timeless(Context(sm.context().GetSite(), 
00532                                  sm.context().GetSimFlag(),
00533                                  TimeStamp(0,0),
00534                                  sm.context().GetDetId()),
00535                          sm.task());
00536     CacheMap_t::iterator it = m_cache.find(timeless);
00537     if (it == m_cache.end()) {
00538         return 0;
00539     }
00540     return it->second;
00541 }
00542 
00543 void DybChannelQualitySvc::clearChannel(const ServiceMode& timeless_sm)
00544 {
00545     CacheMap_t::iterator it = m_cache.find(timeless_sm);
00546     if (it == m_cache.end()) {
00547         return;                 // can't clear what we don't have
00548     }
00549 
00550     delete it->second;
00551     m_cache.erase(it);
00552 }
00553 
00554 const IChannelQuality* DybChannelQualitySvc::channelQuality(const ServiceMode& sm)
00555 {
00556     // First to trivial tests in case users is lazy and re-calls us
00557 
00558     if (sm.context() == m_lastSM.context() && sm.task() == m_lastSM.task()) {
00559         //cerr << "Clean on ServiceMode value" << endl;
00560         return this->get(sm);
00561     }
00562     m_lastSM = sm;
00563 
00564 
00565     // Fresh SM, got to dig deeper
00566 
00567     //cerr << "Checking cache based on " << sm.context().AsString("E") << endl;
00568 
00569     Context ctx = sm.context();
00570     ctx.SetTimeStamp(TimeStamp::GetBOT());
00571     ServiceMode timeless_sm(ctx,sm.task());
00572 
00573     // Get, and make if needed, the DCQ for the given SM, neglecting
00574     // the time.
00575     DybChannelQuality* dcq = 0;
00576     CacheMap_t::iterator it = m_cache.find(timeless_sm);
00577 
00578     try {
00579 
00580         if (it == m_cache.end()) {  // first time to see this SM
00581             DybChanQualCache* dcq_cache = new DybChanQualCache(sm, m_useHV, m_useNoisy);
00582                                 // full SM here!
00583             dcq = new DybChannelQuality(dcq_cache, m_chor, 15.0, m_useHV, m_useNoisy);
00584             m_cache[timeless_sm] = dcq;
00585             //cerr << "New cache based on " << sm.context().AsString("E") << endl;
00586         }
00587         else {                  // been there, done that
00588             dcq = it->second;
00589             bool upped = dcq->cache().update(sm.context().GetTimeStamp());
00590             if (upped) {
00591                 //cerr << "Updated cache based on " << sm.context().AsString("E") << endl;
00592             }
00593 
00594         }
00595 
00596     }
00597     catch (const GaudiException& ge) {
00598         //cerr << "Exception during update: " << ge << " at " << sm.context().AsString("E") << endl;
00599         this->clearChannel(timeless_sm);
00600         dcq = 0;
00601         return 0;
00602     }
00603 
00604     if (dcq && dcq->cache().empty()) {
00605         //cerr << "Got ChannelQuality but it is empty: at " << sm.context().AsString("E") << endl;
00606         this->clearChannel(timeless_sm);
00607         dcq = 0;
00608         return 0;
00609     }
00610 
00611     return dcq;
00612 }
00613 
00614 StatusCode DybChannelQualitySvc::queryInterface(const InterfaceID& riid, 
00615                                                 void** ppvInterface)
00616 {
00617     StatusCode sc = StatusCode::FAILURE;
00618     if (ppvInterface) {
00619         *ppvInterface = 0;
00620     
00621         if (IChannelQualitySvc::interfaceID().versionMatch(riid)) {
00622             *ppvInterface = static_cast<IChannelQualitySvc*>(this);
00623             sc = StatusCode::SUCCESS;
00624             addRef();
00625         }
00626         else sc = Service::queryInterface( riid, ppvInterface );    
00627     }
00628     return sc;
00629 }
00630 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Fri May 16 2014 09:59:59 for DybMetaDataSvc by doxygen 1.7.4