//----------------------------------------------------------------------------- // Apr 18 2001 A.Dominguez: initialization of the STNTUPLE silicon hit block //----------------------------------------------------------------------------- #include "AbsEnv/AbsEnv.hh" #include "Stntuple/obj/TStnEvent.hh" #include "Stntuple/obj/TSvxDataBlock.hh" #include "Stntuple/obj/TSiStripBlock.hh" #include "Stntuple/mod/InitStntupleDataBlocks.hh" #include "TrackingObjects/SiData/SiStrip.hh" #include "TrackingObjects/SiData/SiHit.hh" #include "TrackingObjects/SiData/SiHitSet.hh" #include "TrackingObjects/SiData/SiCluster.hh" #include "TrackingObjects/SiData/SiDataShift.hh" #include "CLHEP/Geometry/Point3D.h" #include #include #include // Stuff for lookup table of SiHit id's #include "Stntuple/mod/SiHitLookup.hh" #include "ErrorLogger_i/gERRLOG.hh" //_____________________________________________________________________________ Int_t StntupleInitSiHit(TStnSiHit& hit, const SiHit& rick, const SiDigiCode& digi) { // initialize STNTUPLE track starting from CDF SiHit HepPoint3D glo(rick.getGlobalPosition()); hit.fGlobal = TVector3(glo.x(),glo.y(),glo.z()); hit.fStripNum = rick.getLocalAsStripNum(); hit.fLocal = rick.getLocalAsMeasured(); hit.fError = rick.getLocalError(); // hit.fQtotal = rick.getQtotal(); // To get the higher precision value for ADC counts, you need to // loop over the strips and use the dataShift class hit.fQtotal=0; hit.fNoise=0; if (rick.getCluster()) { // StripSet exists in event record for (SiCluster::Iterator i=rick.getCluster()->begin(); i!=rick.getCluster()->end(); i++) { float adc =i->dataShift().scaledToFloat(i->getScaledAdc()); float noise=i->dataShift().scaledToFloat(i->getScaledNoise()); hit.fQtotal+=adc; hit.fNoise+=noise*noise; } hit.fNoise=std::sqrt(hit.fNoise); } else { // StripSet does NOT exist in event record. No access to cluster hit.fQtotal=rick.getQtotal(); } hit.fNstrip = rick.getNstrip(); hit.fDigiCode.fDigiCode = digi.getKey(); if (rick.getCluster()) { std::set obsps; rick.getCluster()->getObspNum(obsps); int nobsp=0; if (! obsps.empty()) { // pack the obsp numbers in fUniqueID for (std::set::iterator iobsp=obsps.begin(); iobsp!=obsps.end(); iobsp++) { if (nobsp<2) { hit.SetObsp(nobsp,*iobsp); } nobsp++; } } // Look for bad neighboring strips if (rick.getCluster()->firstStrip()) { if (rick.getCluster()->firstStrip()->hasBadLowNeighbor()) hit.fStatus |= 0x2; if (rick.getCluster()->lastStrip()->hasBadHighNeighbor()) hit.fStatus |= 0x2; } else { errlog(ELerror, "Err:1") << "@SUB=StntupleInitSiHit" << "SiCluster has invalid pointer to strips" << endmsg; } } if (! rick.noBadStrips()) hit.fStatus |= 0x1; hit.fCdfSiHit = (SiHit *)&rick; // Useful for cross referencing things return 0; } //_____________________________________________________________________________ Int_t StntupleInitSvxDataBlock(TStnDataBlock* Block, AbsEvent* Event, int Mode) { // fill silicon hit data block int ev_number, rn_number; // check if block has already been // initialized ev_number = AbsEnv::instance()->trigNumber(); rn_number = AbsEnv::instance()->runNumber(); if (Block->Initialized(ev_number,rn_number)) return 0; TSvxDataBlock* data = (TSvxDataBlock*) Block; data->Clear(); //----------------------------------------------------------------------------- // initialize the lookup table on first call and clear lookup table //----------------------------------------------------------------------------- if (! data->fId) { data->fId = new SiHitLookup(); } SiHitLookup* data_fid = (SiHitLookup*) data->fId; data_fid->map.clear(); EventRecord::ConstIterator it(Event,"SiHitSet"); if (! it.is_valid()) { // No hit list. Go home return -1; } // Assume that we want the first SiHitSet in the event record SiHitSet_ch sh(it); if (sh->nEntries()<=0) { // Hit list is empty, go home. return -1; } else { // Then we need this hack to puff up the hit id's // EventRecord::Iterator ithack(Event,"SiHitSet"); // SiHitSet_h shack(ithack); // SiHit *hack=(*shack)[1]; // const_cast( sh.operator->() )->renumber(); data_fid->map.reserve( sh->size() ); // reserve number of digicodes } // Set the size of the digicode arrays // data->fDigiCodes.Set(sh->nDigiCode()); // data->fDigiCodeFirstHit.Set(sh->nDigiCode()); // data->fDigiCodeLastHit.Set(sh->nDigiCode()); std::vector digiCodes; digiCodes.reserve(sh->nDigiCode()); std::vector digiCodeFirstHit; digiCodeFirstHit.reserve(sh->nDigiCode()); std::vector digiCodeLastHit; digiCodeLastHit.reserve(sh->nDigiCode()); int idigi=0; // Loop over all the SiHit's and make TStnSiHit's out of them for (SiHitSet::const_digi_iterator dit=sh->contents().begin();dit!=sh->contents().end();++dit) { int first=data->fNSiHits; int last=-1; int i=0; data_fid->map[ (*dit).first ].reserve((*dit).second.size()); // reserve number of hits on digi for (SiHitSet::const_iterator sit=(*dit).second.begin(); sit!=(*dit).second.end() ;++sit) { TStnSiHit* siHit = data->NewSiHit(); // new space for 1 TStnSiHit in TClonesArray StntupleInitSiHit( *siHit, **sit, (*dit).first ); data_fid->map[(*dit).first].push_back(data->fNSiHits-1); // Pasha's id of hit if ( i != sh->index(dit,sit).vectorIndex() ) { errlog(ELwarning, "Err:2") << "@SUB=StntupleInitSvxDataBlock" << "SiHit has invalid ID" // <index(dit,sit) << endmsg; data->Clear(); data_fid->map.clear(); return 0; } i++; } // Iterators de-reference to *SiHit if (data->fNSiHits > first) { // There were hits. Save digicode if (idigi>data->fMaxDigiCode) { // lookup information. errlog(ELwarning, "Err:3") << "@SUB=StntupleInitSvxDataBlock" << "StntupleInitSvxDataBlock: Too many detector elements had hits!" << " fMaxDigiCode=" << data->fMaxDigiCode << ", idigi=" << idigi << endmsg; data->Clear(); return -1; } last = (data->fNSiHits)-1; // data->fDigiCodes[idigi] = (*dit).first.getKey(); // data->fDigiCodeFirstHit[idigi] = first; // data->fDigiCodeLastHit[idigi] = last; digiCodes.push_back((*dit).first.getKey()); digiCodeFirstHit.push_back(first); digiCodeLastHit.push_back(last); idigi++; } } // digi_iterators de-reference to if (idigi!=digiCodes.size()) { errlog(ELerror, "Err:4") << "@SUB=StntupleInitSvxDataBlock" << "StntupleInitSvxDataBlock: Inconsistent links to SiDigiCodes!" << " idigi=" << idigi << ", digiCodes.size()=" << digiCodes.size() << endmsg; data->Clear(); return -1; } else { data->fDigiCodes.Set(idigi,&digiCodes[0]); data->fDigiCodeFirstHit.Set(idigi,&digiCodeFirstHit[0]); data->fDigiCodeLastHit.Set(idigi,&digiCodeLastHit[0]); } data->f_EventNumber = ev_number; data->f_RunNumber = rn_number; return 0; } // After both the SvxDataBlock and SiStripBlocks have been filled, // then make links between the two Int_t StntupleSvxDataBlockLinks(TStnDataBlock* Block, AbsEvent* Event, int Mode) { TSvxDataBlock* data = (TSvxDataBlock*) Block; TSiStripBlock* sdata; sdata = (TSiStripBlock* ) Block->GetEvent()->GetDataBlock("SiStripsBlock"); if (! sdata) return 0; // No silicon strips block in event, bail out gracefully if (sdata->fNSiStrips==0) return -1; // No strips in event, bail out and complain // Loop over hits in ntuple block, find link to SiHit*, then fish out // the matching SiStrips and corresponding TStnSiStrips data->SiStripLinkHit()->Init(data->NSiHits()); for (int ihit=0; ihitNSiHits(); ihit++) { const SiHit *h = data->SiHit(ihit)->GetCdfSiHit(); int digi = data->SiHit(ihit)->DigiCode()->fDigiCode; const SiCluster *cl = h->getCluster(); if (cl) { data->SiStripLinkHit()->InitLinks(ihit); for (SiCluster::Iterator si=cl->begin(); si!=cl->end(); si++) { int stripnum = si->getStripNumber(); int stripindex = sdata->FindStrip(digi,stripnum); if (stripindex>=0) data->SiStripLinkHit()->Add(ihit,stripindex); } } } return 0; }