// File: hrichunpackercal99.cc
//
// Author: Walter Schoen <W.Schoen@physik.tu-muenchen.de>
// Last update by Walter Schoen: 99/12/17 17:29:47
// Last update by Thomas Eberl: 02/10/25 14:57:34
//*-- Modified : Tue Feb 15 18:50:45 CET 2005 martin.jurkovic@ph.tum.de
// Event number is obtained from the event header	
// Modified by Michael Weber:
// optional (default = kFALSE) HRichRaw category is filled (formerly known as HRichUnpackerRaw99)
//

#include "TRandom.h"

#include "haddef.h"
#include "hades.h"
#include "hcategory.h"
#include "hdebug.h"
#include "hdetector.h"
#include "hevent.h"
#include "heventheader.h"
#include "hldsubevt.h"
#include "hparset.h"
#include "hrichcal.h"
#include "hrichcalpar.h"
#include "hrichcalparcell.h"
#include "hrichcalsim.h"
#include "hrichdetector.h"
#include "hrichmappingpar.h"
#include "hrichraw.h"
#include "hrichunpackercal99.h"
#include "hrichutilfunc.h"
#include "hruntimedb.h"
#include "hspectrometer.h"
#include "richdef.h"

#include <stdio.h>
#include <stdlib.h>


HRichUnpackerCal99::HRichUnpackerCal99(Int_t rId, Bool_t wrtRaw, Int_t strtEvt,Bool_t isPed,Bool_t verbose,Int_t iSloppyL, Bool_t swap_enabled) {

    richId       = rId;
    writeRaw     = wrtRaw;
    startEvt     = strtEvt;
    isPedestal   = isPed;
    kverbose     = verbose;
    iSloppyLevel = iSloppyL;

    //Introduced April 2003 to compensate for cable swapping in readout electronics
    //Enable this flag only if you intend to analyze nov 01 data.
    perform_cable_swapping=swap_enabled;
    nSubEvtCntr = 0;
    nSecMisMatchCntr = 0;
    pRawCat=NULL;
    pCalCat=NULL;
    fEventNr = -1;
    if (startEvt !=0) cout<<"For SubEvtId "<<richId<<
			  " starting to unpack at evt # "<<startEvt<<endl;
    switch (richId){
    case 100:
	SubEvtIdSec=0;
	break;
    case 101:
	SubEvtIdSec=0;
	break;
    case 102:
	SubEvtIdSec=1;
	break;
    case 103:
	SubEvtIdSec=1;
	break;
    case 104:
	SubEvtIdSec=2;
	break;
    case 105:
	SubEvtIdSec=2;
	break;
    case 106:
	SubEvtIdSec=3;
	break;
    case 107:
	SubEvtIdSec=3;
	break;
    case 108:
	SubEvtIdSec=4;
	break;
    case 109:
	SubEvtIdSec=4;
	break;
    case 110:
	SubEvtIdSec=5;
	break;
    case 111:
	SubEvtIdSec=5;
	break;
    }
   
}
HRichUnpackerCal99::~HRichUnpackerCal99(void) {
}
Bool_t HRichUnpackerCal99::init(void) {
  HRichDetector *pRichDet = (HRichDetector*)gHades->getSetup()
	->getDetector("Rich");

  if( kTRUE == writeRaw)
    {
      pRawCat=gHades->getCurrentEvent()->getCategory(catRichRaw);
      if (!pRawCat) {
	pRawCat=pRichDet->buildCategory(catRichRaw);
	if (!pRawCat) {
	  return kFALSE;
	} else {
	  gHades->getCurrentEvent()->addCategory(catRichRaw,pRawCat,"Rich");
	}
      }
    }
  
    pCalCat=gHades->getCurrentEvent()->getCategory(catRichCal);
    if (!pCalCat) {
	if(gHades->getEmbeddingMode()==0){
	    pCalCat=pRichDet->buildCategory(catRichCal);
	}
	else {
	    pCalCat = pRichDet->buildMatrixCat("HRichCalSim",1);
	}
	if (!pCalCat) return kFALSE;
	else gHades->getCurrentEvent()
		 ->addCategory(catRichCal, pCalCat, "Rich");
    }
    initCalPar();
    initMappingPar();
    return kTRUE;
}

void HRichUnpackerCal99::initMappingPar(void){
    HRuntimeDb* rtdb=gHades->getRuntimeDb();
    pMapPar = rtdb->getContainer("RichMappingParameters");
}

Int_t HRichUnpackerCal99::getSubEvtId(void) const {
    return richId; 
}

void HRichUnpackerCal99::printDataWord(DataWord &addr,Int_t ch){
    cout<<"*****************************************************************************"<<endl;
    cout<<"Event Nr: "<<fEventNr<<endl;
    cout<<"SEC: "<<addr.sector<<" RC: "<<addr.controler<<" PORT: "<<addr.port<<" MOD: "
	<<addr.modul<<" CH: "<<addr.channel<<" CHRG: "<<ch<<endl;
}

void HRichUnpackerCal99::printMapping(DataWord &addr){
    cout<<"Event Nr: "<<fEventNr<<endl;
    cout<<"Col: "<<getMappingPar()->getCol(getUpi(addr))<<endl;
    cout<<"Row: "<<getMappingPar()->getRow(getUpi(addr))<<endl;
    cout<<"isValidUpi: "<<getMappingPar()->isValidUpi(getUpi(addr))<<endl;
    HLocation loc;
    loc.set(3,0,0,0);
    loc.setOffset(getMappingPar()->getCol(getUpi(addr)));
    loc.setIndex(1,getMappingPar()->getRow(getUpi(addr)));
    loc.setIndex(0,addr.sector);
    printCalParCell(loc);
    cout<<"*****************************************************************************"<<endl;
}

Bool_t  HRichUnpackerCal99::testSubEvt(DataWord &addr,Int_t ch){
    if (kverbose) printDataWord(addr,ch);
    Bool_t debugOutput = kFALSE;
    Bool_t decision = kTRUE;
    if (iSloppyLevel < 3){
 Int_t upi = getUpi(addr);
	//	cout<<"testSubEvt: upi: "<<upi<<endl;
	// *** check if address is within reasonable boundaries
	if (ch >=0 && ch<1024){
	    if (addr.channel>=0 && addr.channel<64){ 
		if (addr.modul>=0 && addr.modul<5){ 
		    if (addr.port>=0 && addr.port<8){
			if (addr.controler >=0 && addr.controler<2){
			    if (addr.sector>=0 && addr.sector<6){
				if (upi>=0 && upi<17464){//redundant 
				    if (getMappingPar()->isValidUpi(upi)){//
					if (getMappingPar()->getCol(upi)>0 
					    && getMappingPar()->getCol(upi)<92){//redundant
					    //cout<<"col: "<<getMappingPar()->getCol(upi)<<endl;
					    if (getMappingPar()->getRow(upi)>0 
						&& getMappingPar()->getRow(upi)<90){//redundant
						//cout<<"row: "<<getMappingPar()->getRow(upi)<<endl;
						if (kverbose) printMapping(addr);
					    }else{
						if (iSloppyLevel < 2 && debugOutput){
						    cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in" 
							<<" HRichUnpackerCal99::testSubEvt ***"
							<<" unpacked row "
							<<getMappingPar()->getRow(upi)
							<<" is out of bounds [0;89]"<<endl;
						}
						decision=kFALSE; 
					    }
					}else{
					    if (iSloppyLevel < 2 && debugOutput){
						//cout<<"SloppyLevel: "<<iSloppyLevel<<endl;
						cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in" 
						    <<" HRichUnpackerCal99::testSubEvt ***"
						    <<"  unpacked col "
						    <<getMappingPar()->getCol(upi)
						    <<" is out of bounds [0;91]"<<endl;
					    }
					    decision=kFALSE;
					}
				    }else{
					//cout<<"not a valid upi"<<endl;
					if((getMappingPar()->isUnConnCh(upi))){
					  //TRUE
					  //cout<<"not a valid upi"<<endl;
					    if(isPedestal){
					      //TRUE TRUE -> FALSE
						nSubEvtCntr--;
						decision=kFALSE;
					    }else{ //FALSE TRUE -> FALSE
						if (iSloppyLevel < 2 && debugOutput){
						    cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in"
							<<" HRichUnpackerCal99::testSubEvt ***"
							<<" unpacked channel "<<upi
							<<" exists, but is not connected to any pad."
							<<" It is allowed only in a pedestal run !"<<endl;
						}
						decision=kFALSE;
					    }
					}else{ //FALSE (FALSE FALSE | TRUE FALSE -> FALSE
					    if (iSloppyLevel < 2 && debugOutput){
						    cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in" 
							<<" HRichUnpackerCal99::testSubEvt ***"
							<<" unpacked channel "<<upi
							<<" does not exist"<<endl;
					    }
						decision=kFALSE;
					}
				    }
				}else{
				    if (iSloppyLevel < 2 && debugOutput){
					cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in" 
					    <<" HRichUnpackerCal99::testSubEvt ***"
					    <<" unpacked channel "<<upi
					    <<" is out of bounds [0;17463]"<<endl;
				    }
				    decision=kFALSE;
				}
			    }else{
				if (iSloppyLevel < 2 && debugOutput){
				    cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in" 
					<<" HRichUnpackerCal99::testSubEvt ***"
					<<" unpacked sector "<<addr.sector
					<<" is out of bounds [0;5]"<<endl;
				}
				decision=kFALSE;
			    }
			}else{
			    if (iSloppyLevel < 2 && debugOutput){
				cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in" 
				    <<" HRichUnpackerCal99::testSubEvt ***"
				    <<" unpacked controler "<<addr.controler
				    <<" is out of bounds [0;1]"<<endl;
			    }
			    decision=kFALSE;
			}
		    }else{
			if (iSloppyLevel < 2 && debugOutput){
			    cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in" 
				<<" HRichUnpackerCal99::testSubEvt ***"
				<<" unpacked port "<<addr.port
				<<" is out of bounds [0;4]"<<endl;
			}
			decision=kFALSE;
		    }
		}else{
		    if (iSloppyLevel < 2 && debugOutput){
			cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in" 
			    <<" HRichUnpackerCal99::testSubEvt ***"
			    <<" unpacked module "<<addr.modul
			    <<" is out of bounds [0;4]"<<endl;
			printMapping(addr);
			printDataWord(addr,ch);
		    }
		    decision=kFALSE;
		}
	    }else{
		if (iSloppyLevel < 2 && debugOutput){
		    cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in" 
			<<" HRichUnpackerCal99::testSubEvt ***"
			<<" unpacked channel "<<addr.channel
			<<" is out of bounds [0;63]"<<endl;
		    printMapping(addr);
		    printDataWord(addr,ch);
		}
		decision=kFALSE;
	    }
	}else{
	    if (iSloppyLevel < 2 && debugOutput){
		cout<<"SubEvtId "<<getSubEvtId()<<":ERROR (evt nr: "<<fEventNr<<") in" 
		    <<" HRichUnpackerCal99::testSubEvt ***"
		    <<" unpacked charge "<<ch
		    <<" is out of bounds [0;1023]"<<endl;
	    }
	    decision=kFALSE;
	}
    }
    if (decision == kFALSE) nSubEvtCntr++;
    return decision;
}

Int_t HRichUnpackerCal99::getUpi(DataWord &addr){
  //swapping of rich electronics coordinates!!!
  if(perform_cable_swapping){
    if(addr.controler==0 && addr.sector==3 && addr.port==6)
      {
	return addr.controler*10000 + 4*1000 + addr.modul*100 + addr.channel;
      }
    if(addr.controler==0 && addr.sector==3 && addr.port==4)
      {
	return addr.controler*10000 + 6*1000 + addr.modul*100 + addr.channel;
      }
  }
  return addr.controler*10000 + addr.port*1000 + addr.modul*100 + addr.channel;
}

Int_t HRichUnpackerCal99::execute() {
  HLocation loc;
  Bool_t debugOutput = kFALSE;
  loc.set(3,0,0,0);
//   fEventNr++;
  fEventNr = gHades->getCurrentEvent()->getHeader()->getEventSeqNumber();

  if (fEventNr>=startEvt){
      if (pSubEvt) {   
	  for (UInt_t i = 0; i < pSubEvt->getDataLen(); i++) {
	      charge = pSubEvt->getData()[i]  & 0x3FF;   
	      dataword.channel =  (pSubEvt->getData()[i] >> 10) & 0x3F;
	      dataword.modul =  (pSubEvt->getData()[i] >> 16) & 0x7;
	      dataword.port =  (pSubEvt->getData()[i] >> 19) & 0x7;
	      dataword.controler = (pSubEvt->getData()[i] >>22) & 0x1 ; 
	      dataword.sector =  (pSubEvt->getData()[i] >>23) & 0x7;
	      if (dataword.sector == SubEvtIdSec){ //check sector consistency
		if (testSubEvt(dataword,charge)){ //check if pad is valid
		  loc.setOffset(getMappingPar()->getCol(getUpi(dataword)));
		  loc.setIndex(1,getMappingPar()->getRow(getUpi(dataword)));
		  loc.setIndex(0,dataword.sector);
		  if (getMappingPar()->isReadOut(loc[2],loc[1])){
		    if (loc.getIndex(1) >= 0 && loc.getOffset() >= 0) {
 
		      if( kTRUE == writeRaw)
			{
			  HRichRaw* pCell =
			    (HRichRaw*) pRawCat->getSlot(loc); 
			  if (pCell!=NULL) {
			    // add a random nb [0;1] to account 
			    // for the cut-off in the ADC
			    pCell=new(pCell) 
			      HRichRaw(charge+gRandom->Rndm());
			    pCell->setSector(loc[0]);
			    pCell->setRow(loc[1]);
			    pCell->setCol(loc[2]);
			    pCell->setEventNr(fEventNr);
			  }
			}
		    
		    
		      HRichCalParCell *calparcell = NULL;
		      HRichCal *pCalCell = NULL;
		      calparcell = (HRichCalParCell*) ((HRichCalPar*)getCalPar())
			->getObject(loc);
		      // subtract measured mean value and add a random nb
		      // [0;1] to account for the cut-off in the ADC
		      Float_t fCharge = charge    * 
			  calparcell->getSlope()  - 
			  calparcell->getOffset() + 
                          gRandom->Rndm();
		      if (fCharge > 0.0) { 
			pCalCell = (HRichCal *)pCalCat->getSlot(loc);
			if (pCalCell != NULL) {

			    if(gHades->getEmbeddingMode()==0){
			      pCalCell = new(pCalCell) HRichCal;
			    } else {
                              pCalCell = new(pCalCell) HRichCalSim;
			    }
			  pCalCell->setCharge(fCharge);
			  pCalCell->setSector(loc[0]);
			  pCalCell->setRow(loc[1]);
			  pCalCell->setCol(loc[2]);
			  pCalCell->setEventNr(fEventNr);
			}
		      }
		    }
		  }else{
		    cout<<"SubEvtId "<<getSubEvtId()<<" (HRichUnpackerCal99::execute) Error in event :"
			<<fEventNr<<endl;
		    cout<<"Pad col: "<<loc[2]<<" row: "<<loc[1]
			<<" sec: "<<loc[0]<<" chrg: "<<charge
			<<" is invalid and slipped through testSubEvt"<<endl;
		    cout<<"printDataWord says:"<<endl;
		    printDataWord(dataword,charge);
		    cout<<"printMapping says:"<<endl;
		    printMapping(dataword);
		  }
		}else{
		  if (iSloppyLevel<2 && debugOutput) {
		    if (!isPedestal){
		      cout<<"RICH: Dataword skipped in Event: "
			  <<fEventNr<<endl;
		    }
		  }
		}
	      }else{
		nSecMisMatchCntr++;
		if (iSloppyLevel<1){
		  cout<<"Error in event :"<<fEventNr<<endl;
		  cout<<"Unpacked sector info: "<<dataword.sector<<
		    "  SubEvtId claims sector: "<<SubEvtIdSec<<endl;
		  cout<<"RICH: Dataword skipped"<<endl;
		}
	      }
	  }//end of unpacking sub event
      }// end of if data in subevent      
  }// end of start event condition   
  return kTRUE;
}

Bool_t HRichUnpackerCal99::finalize(void) {
  //Int_t id = getSubEvtId(); // unused
  //cout<<"SubEvtId:"<<id<<" RICH: Number of evts processed: "<<fEventNr+1<<endl;
  //cout<<"SubEvtId:"<<id<<" RICH: Sloppy level:             "<<iSloppyLevel<<endl;
  //cout<<"SubEvtId:"<<id<<" RICH: Corrupt datawords:        "<<nSubEvtCntr<<endl;
  //cout<<"SubEvtId:"<<id<<" RICH: Sector mismatch errors:   "<<nSecMisMatchCntr<<endl;
  return kTRUE;
}

void HRichUnpackerCal99::printCalParCell(HLocation& loc) {
    HRichCalParCell *calparcell = NULL;
    calparcell = (HRichCalParCell*) ((HRichCalPar*)getCalPar())
	->getObject(loc);
    cout<<"SEC: "<<loc[0]<<" ROW: "<<loc[1]<<" COL: "<<loc[2]<<
	" OFFSET: "<<calparcell->getOffset()<<" SIGMA : "<<
	calparcell->getSigma()<<" SLOPE : "<<calparcell->getSlope()<<
	endl;
} 

void HRichUnpackerCal99::initCalPar() {
  HRuntimeDb* rtdb=gHades->getRuntimeDb();
  fCalPar = rtdb->getContainer("RichCalPar");
}

ClassImp(HRichUnpackerCal99) 








Last change: Sat May 22 13:10:37 2010
Last generated: 2010-05-22 13:10

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.