/////////////////////////////////////////////////////////////////////////////// // fill KINE branches of GEANT ROOT tree // // last modified on 08/12/2008 by I. Koenig /////////////////////////////////////////////////////////////////////////////// #include "fillkine.h" #include "cfortran.h" #include "hgeantheader.h" #include "hgeantkine.h" #include "hgeantrich.h" #include "hades.h" #include "hlocation.h" #include "hlinearcategory.h" #include "hmatrixcategory.h" #include "hrecevent.h" #include "hpartialevent.h" #include "heventheader.h" #include "hgeantmaxtrk.h" struct KINE_DEF { // structure mapped to KINETUPS Fortran COMMON block Int_t eventid; Int_t runid; Float_t ebeam; Float_t bpar; Float_t phi_event; Int_t ntrk; Int_t track[MAXTRKKINE]; Int_t prevtrack[MAXTRKKINE]; Float_t tvert[MAXTRKKINE][3]; Int_t mechanism[MAXTRKKINE]; Int_t partid[MAXTRKKINE]; Float_t pmom[MAXTRKKINE][3]; Float_t gene1[MAXTRKKINE]; Float_t gene2[MAXTRKKINE]; Float_t gene3[MAXTRKKINE]; Float_t wghtp[MAXTRKKINE]; Float_t userval[MAXTRKKINE]; Int_t eventVersion; }; #define KINETUPS COMMON_BLOCK(KINETUPS,kinetups) COMMON_BLOCK_DEF(KINE_DEF,KINETUPS); void fillkine(void) { // copy tracks from common block into kine category // mark all primary particles (parent=0) as active HLocation loc; HRecEvent* pHGeantEvent = (HRecEvent*)(gHades->getCurrentEvent()); // get pointer to event HPartialEvent* pKine = pHGeantEvent->getPartialEvent(catSimul); HCategory* cat; HGeantHeader* pHGeantHeader = (HGeantHeader*)(pKine->getSubHeader()); pHGeantHeader->setEventId(KINETUPS.eventid); // fill in data members pHGeantHeader->setBeamEnergy(KINETUPS.ebeam); pHGeantHeader->setImpactParameter(KINETUPS.bpar); pHGeantHeader->setEventPlane(KINETUPS.phi_event); pHGeantEvent->getHeader()->setId(0); // set event identifier pHGeantEvent->getHeader()->setVersion((UInt_t)KINETUPS.eventVersion); // and event version in // HRecEvent header pHGeantEvent->getHeader()->setEventSeqNumber((UInt_t)KINETUPS.eventid); //ID pHGeantEvent->getHeader()->setEventRunNumber((UInt_t)KINETUPS.runid); //run pHGeantEvent->getHeader()->setDate(getDAQDate()); pHGeantEvent->getHeader()->setTime(getDAQTime()); cat = pKine->getCategory(catGeantKine); // get new category cat->Clear(); // clear category int counter = 1; for(int trk=0; trk counter) { // here GEANT skipped a track nb, // we insert dummy slots to sync for(int j=counter; jgetNewSlot(loc); pHGeantKine = new(pHGeantKine) HGeantKine; counter++; } } loc.set(0); // set to 0 indices, so that locator returns next slot HGeantKine* pHGeantKine = (HGeantKine*)cat->getNewSlot(loc); // get slot if(pHGeantKine==NULL) { printf("\n*** FILLKINE: HGeantKine location not found ! ***\n"); return; } pHGeantKine = new(pHGeantKine) HGeantKine; // KINE track data pHGeantKine->setParticle(KINETUPS.track[trk],KINETUPS.partid[trk]); Int_t medium = KINETUPS.mechanism[trk]/1000; Int_t mech = KINETUPS.mechanism[trk] - 1000*medium; pHGeantKine->setCreator(KINETUPS.prevtrack[trk],medium,mech); pHGeantKine->setVertex(KINETUPS.tvert[trk][0], KINETUPS.tvert[trk][1], KINETUPS.tvert[trk][2]); pHGeantKine->setMomentum(KINETUPS.pmom[trk][0], KINETUPS.pmom[trk][1], KINETUPS.pmom[trk][2]); pHGeantKine->setGenerator(KINETUPS.gene1[trk],KINETUPS.gene2[trk],KINETUPS.gene3[trk]); pHGeantKine->setWeight(KINETUPS.wghtp[trk]); if (KINETUPS.prevtrack[trk] == 0) pHGeantKine->setActive(kTRUE); // mark primary track as active pHGeantKine->setUserVal(KINETUPS.userval[trk]); counter++; } } // wrapping of the c++ routine as Fortran-subroutine using cfortran.h // of Cern-library FCALLSCSUB0(fillkine,FILLKINE,fillkine) #include UInt_t getDAQTime(void) { // return GMT time in HADES DAQ format time_t tempo; struct tm *gmTime; UInt_t t; tempo = time(NULL); gmTime = gmtime(&tempo); t = 0; t |= gmTime->tm_hour << 16; t |= gmTime->tm_min << 8; t |= gmTime->tm_sec; return t; } UInt_t getDAQDate(void) { // return date in HADES DAQ format time_t tempo; struct tm *gmTime; UInt_t d; tempo = time(NULL); gmTime = gmtime(&tempo); d = 0; d |= gmTime->tm_year << 16; d |= gmTime->tm_mon << 8; d |= gmTime->tm_mday; return d; } void finalizekine(Int_t* compress) { // 1) Tracks participating in a hit have been marked implicitely active, // mark now also their parents, grandparents, etc. // All primaries have already been marked in fillkine(). // Rich direct hits and mirror hits need however special treatment as // they are not (yet) supported in the HGeantKine hit index scheme. // 2) Delete (if compress==1) all inactive tracks from the kine category. // HLinearCategory* pKine; pKine = (HLinearCategory*)gHades->getCurrentEvent() ->getCategory(catGeantKine); HMatrixCategory *pRichDirect, *pRichMirror; pRichDirect = (HMatrixCategory*)gHades->getCurrentEvent() ->getCategory(catRichGeantRaw+1); pRichMirror = (HMatrixCategory*)gHades->getCurrentEvent() ->getCategory(catRichGeantRaw+2); TIterator* iterDirect = NULL; TIterator* iterMirror = NULL; if (pRichDirect != NULL) { // need to set all Rich direct-hit tracks active iterDirect = pRichDirect->MakeIterator("native"); iterDirect->Reset(); HGeantRichDirect* pDirectHit; Int_t trk, id; while ( (pDirectHit = (HGeantRichDirect*)iterDirect->Next()) != NULL) { pDirectHit->getTrack(trk,id); ( (HGeantKine*)pKine->getObject(trk-1) )->setActive(kTRUE); } } if (pRichMirror != NULL) { // set likewise all mirror-hit tracks active iterMirror = pRichMirror->MakeIterator("native"); iterMirror->Reset(); HGeantRichMirror* pMirrorHit; Int_t trk, id; while ( (pMirrorHit = (HGeantRichMirror*)iterMirror->Next()) != NULL) { pMirrorHit->getTrack(trk,id); ( (HGeantKine*)pKine->getObject(trk-1) )->setActive(kTRUE); } } Int_t ntrks = pKine->getEntries(); // set now parent tracks, etc. active HGeantKine *pHGeantKine=NULL; for(Int_t track=1; track<=ntrks; track++) { pHGeantKine = (HGeantKine*)pKine->getObject(track-1); if (pHGeantKine == NULL) continue; if ( !pHGeantKine->isPrimary() && pHGeantKine->isActive() ) { HGeantKine::setChainActive(track,kTRUE,pKine); } } if (*compress==1) { // compress kine category and re-index all hit categories Int_t index=1; for(Int_t track=1; track<=ntrks; track++) { // loop again over all tracks pHGeantKine = (HGeantKine*)pKine->getObject(track-1); if (!pHGeantKine->isActive()) pKine->getSlot(track-1) = NULL; else { pHGeantKine->setNewTrackNumber(index); index++; } } // Re-index as well HGeantRichDirect and HGeantRichMirror // if (pRichDirect != NULL) { iterDirect->Reset(); Int_t oldTrack, newTrack, id; HGeantRichDirect* pDirectHit; while ( (pDirectHit = (HGeantRichDirect*)iterDirect->Next() ) != NULL) { // iterate direct hits and update their track number pDirectHit->getTrack(oldTrack,id); newTrack = ( (HGeantKine*)pKine->getObject(oldTrack-1) )->getTrack(); pDirectHit->setTrack(newTrack,id); } delete iterDirect; } if (pRichMirror != NULL) { iterMirror->Reset(); Int_t oldTrack, newTrack, id; HGeantRichMirror* pMirrorHit; while ( (pMirrorHit = (HGeantRichMirror*)iterMirror->Next() ) != NULL) { // iterate mirror hits and update their track number pMirrorHit->getTrack(oldTrack,id); newTrack = ( (HGeantKine*)pKine->getObject(oldTrack-1) )->getTrack(); pMirrorHit->setTrack(newTrack,id); } delete iterMirror; } Int_t oldParent, newParent; for(Int_t track=1; track<=ntrks; track++) { // update now parent numbers pHGeantKine = (HGeantKine*)pKine->getObject(track-1); if (pHGeantKine == NULL) continue; if ( (oldParent = pHGeantKine->getParentTrack() ) > 0) { newParent = ( (HGeantKine*)pKine->getObject(oldParent-1) )->getTrack(); pHGeantKine->setParentTrack(newParent); } } pKine->Compress(); // ...finally remove empty slots. Uff! } for(Int_t track=1; track<=ntrks; track++) { // fill acceptance bits for detectors pHGeantKine = (HGeantKine*)pKine->getObject(track-1); if (pHGeantKine == NULL) continue; pHGeantKine->fillAcceptanceBit(); } } // wrapping of the c++ routine as Fortran-subroutine using cfortran.h // of Cern-library FCALLSCSUB1(finalizekine,FINALIZEKINE,finalizekine,PINT)