TOF DA for online calibration
-- "Contact:" - Chiara.Zampolli@bo.infn.it
-- "Link:" - www.bo.infn.it/~zampolli
-- "Run Type:" - PHYSICS
-- "DA Type:" - MON
-- "Number of events needed:" depending on the run, being run-level
-- "Input Files:" - TOFdaTotal.root, to be updated if existing
-- "Output Files:" - TOFdaRun.root, TOFdaTotal.root, both to be exported to the DAQ FXS
-- "Trigger types used:" - PHYSICS_EVENT
+Contact: Chiara.Zampolli@bo.infn.it
+ Roberto.Preghenella@bo.infn.it
+
+Run Type: PHYSICS
+DA Type: MON
+Number of events needed:
+Input Files: no input
+Output Files: TOFdaHits.root
+Event types used: PHYSICS_EVENT
*/
-#define FILE_TOTAL "TOFdaTotal.root"
-#define FILE_RUN "TOFdaRun.root"
+#define FILE_HITS "TOFdaHits.root"
+#define FILE_CALIB "TOFdaCalib.root"
// DATE
-#include <daqDA.h>
-#include <event.h>
-#include <monitor.h>
+#include "event.h"
+#include "monitor.h"
+#include "daqDA.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
//AliRoot
-#include <AliTOFRawStream.h>
-#include <AliRawReaderDate.h>
-#include <AliRawReader.h>
-#include <AliTOFGeometry.h>
-#include <AliT0RawReader.h>
-#include <AliDAQ.h>
-#include <AliTOFHitData.h>
-#include <AliTOFHitDataBuffer.h>
+#include "TROOT.h"
+#include "AliTOFRawStream.h"
+#include "AliRawReaderDate.h"
+#include "AliRawReader.h"
+#include "AliDAQ.h"
+#include "AliTOFHitData.h"
+#include "AliTOFHitDataBuffer.h"
+#include "AliTOFDaConfigHandler.h"
+#include "AliTOFHitField.h"
+#include "AliLog.h"
+#include "AliTOFGeometry.h"
//ROOT
-#include <TFile.h>
-#include <TKey.h>
-#include <TH2S.h>
-#include <TObject.h>
-#include <TMath.h>
-#include <TSystem.h>
-
+#include "TFile.h"
+#include "TKey.h"
+#include "TH2S.h"
+#include "TObject.h"
+#include "TMath.h"
+#include "TSystem.h"
+#include "TROOT.h"
+#include "TPluginManager.h"
+#include "TSAXParser.h"
+#include "TTree.h"
/* Main routine
Arguments:
1- monitoring data source
*/
-
-int main(int argc, char **argv) {
+int
+main(int argc, char **argv)
+{
- AliTOFGeometry * geom = new AliTOFGeometry();
-
- static const Int_t size = AliTOFGeometry::NPadXSector()*AliTOFGeometry::NSectors();
- static const Int_t nbins = 500;
- static const Int_t binmin = -20;
- const Float_t c = 2.99792458E10; //speed of light
- TH1F::AddDirectory(0);
- TH2S * htofPartial = new TH2S("htof","histo with delays", size,-0.5,size*1.-0.5,nbins,binmin-0.5,nbins*1.+binmin-0.5);
+ /* magic line from Rene */
+ gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
+ "*",
+ "TStreamerInfo",
+ "RIO",
+ "TStreamerInfo()");
- // decoding the events
+
+ /* log start of process */
+ printf("TOF DA started\n");
- int status;
+ /* check that we got some arguments = list of files */
if (argc!=2) {
printf("Wrong number of arguments\n");
return -1;
}
- /* define data source : this is argument 1 */
- status=monitorSetDataSource( argv[1] );
- if (status!=0) {
- printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
+ /*
+ * CONFIG
+ */
+
+ /* retrieve config file */
+ int getConfigFile = daqDA_DB_getFile("TOFPhysicsConfig.xml","TOFPhysicsConfig.xml");
+ if (getConfigFile != 0){
+ printf("Failed to retrieve config file from DB! returning...\n");
return -1;
}
-
- /* declare monitoring program */
- status=monitorDeclareMp( __FILE__ );
- if (status!=0) {
- printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
+ /* parse config file */
+ AliTOFDaConfigHandler* tofHandler = new AliTOFDaConfigHandler();
+ TSAXParser *parser = new TSAXParser();
+ parser->ConnectToHandler("AliTOFDaConfigHandler", tofHandler);
+ if (parser->ParseFile("./TOFPhysicsConfig.xml") != 0) {
+ printf("Failed parsing config file! retunring... \n");
return -1;
}
+ /* setup config params */
+ Int_t meanMultiplicity = tofHandler->GetMeanMultiplicity(); /* average expected TOF multiplicity */
+ Int_t maxHits = tofHandler->GetMaxHits(); /* max number of hits to be collected */
+ printf("current settings:\n");
+ printf(" - meanMultiplicity = %d\n", meanMultiplicity);
+ printf(" - maxHits = %d\n", maxHits);
+ /* constants */
+ const Int_t nChannels = 157248;
+ Int_t noiseCheckTrigger = 10; /* first noise check after 10 events */
+ Float_t meanChannelRate = (Float_t)meanMultiplicity / (Float_t)nChannels; /* average expected channel rate (hits/event) */
+ Float_t noiseThreshold = 10. * meanChannelRate; /* noise threshold (hits/event) */
+ Int_t minNoiseHits = 10; /* min number of channel hits to check noise */
+ /* counters and flags */
+ Int_t nPhysicsEvents, nCalibEvents, totHits;
+ Int_t nChHits[nChannels];
+ Bool_t inhibitCollection;
+ Bool_t noiseFlag[nChannels];
+ /* variables */
+ Int_t nhits, ddl, slot, trm, chain, tdc, channel, index, timebin, totbin, deltaBC, l0l1latency, det[5], dummy;
+ Float_t noiseHitThreshold;
- /* define wait event timeout - 1s max */
- monitorSetNowait();
- monitorSetNoWaitNetworkTimeout(1000);
+ /*
+ * INIT
+ */
+
+ /* init counters and flags */
+ nPhysicsEvents = 0;
+ nCalibEvents = 0;
+ totHits = 0;
+ inhibitCollection = kFALSE;
+ for (Int_t ich = 0; ich < nChannels; ich++) {
+ nChHits[ich] = 0;
+ noiseFlag[ich] = kFALSE;
+ }
+
+ /* TOF raw data handling */
+ AliTOFRawStream *rawStream = new AliTOFRawStream();
+ AliTOFHitDataBuffer *pdb = NULL;
+ AliTOFHitData *hit = NULL;
- /* log start of process */
- printf("TOF DA started\n");
+ /* open HITS output file */
+ TFile *fileOutHits = new TFile(FILE_HITS, "RECREATE");
+ /* create hit field data structure */
+ AliTOFHitField *hitField = new AliTOFHitField();
+ /* create temporary tree */
+ TTree *tempTree = new TTree("tempTree", "temporary tree");
+ tempTree->Branch("hit", "AliTOFHitField", &hitField);
+ /* create output tree */
+ TTree *outTree = new TTree("hitTree", "hit tree");
+ outTree->Branch("hit", "AliTOFHitField", &hitField);
+
+ /* open CALIB output file */
+ TFile *fileOutCalib = new TFile(FILE_CALIB, "RECREATE");
+ /* create calib hit histo */
+ TH1F *hCalibHit = new TH1F("hCalibHit", "Calibration events;index;N_{hits}/N_{events}", nChannels, 0., nChannels);
- /* init some counters */
- int nevents_physics=0;
- int nevents_total=0;
+ /*
+ * ONLINE MONITOR
+ */
+ AliLog::SetGlobalLogLevel(AliLog::kFatal);
struct eventHeaderStruct *event;
- eventTypeType eventT;
- Int_t iev=0;
+ int ret;
+ /* define data source : this is argument 1 */
+ ret = monitorSetDataSource(argv[1]);
+ if (ret != 0) {
+ printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(ret));
+ return -1;
+ }
+ /* declare monitoring program */
+ ret = monitorDeclareMp("tofDA");
+ if (ret != 0) {
+ printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(ret));
+ return -1;
+ }
+ /* define wait event timeout - 1s max */
+ monitorSetNowait();
+ monitorSetNoWaitNetworkTimeout(1000);
- /* main loop (infinite) */
- for(;;) {
+ /* loop over events */
+ while (1) {
/* check shutdown condition */
- if (daqDA_checkShutdown()) {break;}
+ if (daqDA_checkShutdown()) break;
+ /*
+ * NOISE CHECK
+ */
+
+ /* check inhibit collection */
+ if (!inhibitCollection) {
+ /* check number of events and check noise */
+ if (nPhysicsEvents >= noiseCheckTrigger || totHits >= maxHits) {
+ noiseHitThreshold = noiseThreshold * nPhysicsEvents;
+ printf("noise check triggered after %d events: threshold is %f hits\n", nPhysicsEvents, noiseHitThreshold);
+ /* loop over all channels */
+ for (Int_t ich = 0; ich < nChannels; ich++) {
+ /* check */
+ if (nChHits[ich] < minNoiseHits || noiseFlag[ich] || nChHits[ich] < noiseHitThreshold) continue;
+ printf("channel %d tagged as noisy (%d hits): disabled\n", ich, nChHits[ich]);
+ noiseFlag[ich] = kTRUE;
+ totHits -= nChHits[ich];
+ } /* end of loop over all channels */
+ /* set new noise check trigger value */
+ noiseCheckTrigger *= 10;
+ } /* end of noise check */
+
+ /* inhibit hit collection when maximum number of hits exceeded */
+ if (totHits >= maxHits) {
+ printf("maximum number of hits exceeded (%d): inhibit hit collection\n", maxHits);
+ inhibitCollection = kTRUE;
+ }
+ }
+
+ /*
+ * GET EVENT
+ */
+
/* get next event (blocking call until timeout) */
- status=monitorGetEventDynamic((void **)&event);
- if (status==MON_ERR_EOF) {
+ ret = monitorGetEventDynamic((void **)&event);
+ if (ret == MON_ERR_EOF) {
printf ("End of File detected\n");
break; /* end of monitoring file has been reached */
}
-
- if (status!=0) {
- printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
+ if (ret != 0) {
+ printf("monitorGetEventDynamic() failed (ret=%d errno=%d): %s\n", ret, errno, monitorDecodeError(ret));
break;
}
-
/* retry if got no event */
- if (event==NULL) {
+ if (event==NULL) continue;
+ /* check event type */
+ if (event->eventType != PHYSICS_EVENT && event->eventType != CALIBRATION_EVENT) {
+ free(event);
+ continue;
+ }
+ /* check inhibit collection */
+ if (event->eventType == PHYSICS_EVENT && inhibitCollection) {
+ free(event);
continue;
}
+ /* increment number of physics events */
+ if (event->eventType == PHYSICS_EVENT) nPhysicsEvents++;
+ /* increment number of calib events */
+ if (event->eventType == CALIBRATION_EVENT) nCalibEvents++;
+
+ /*
+ * DECODE EVENT
+ */
- iev++;
+ /* create raw reader */
+ AliRawReader *rawReader = new AliRawReaderDate((void *)event);
+ /* setup raw stream */
+ rawStream->SetRawReader(rawReader);
+ /* reset buffers */
+ rawStream->ResetBuffers();
+ /* decode */
+ rawStream->DecodeDDL(0, AliDAQ::NumberOfDdls("TOF") - 1, 0);
- /* use event - here, just write event id to result file */
- nevents_total++;
- eventT=event->eventType;
- switch (event->eventType){
-
- /* START OF RUN */
- case START_OF_RUN:
- break;
- /* END START OF RUN */
-
- /* END OF RUN */
- case END_OF_RUN:
- break;
-
- case PHYSICS_EVENT:
- nevents_physics++;
- AliRawReader *rawReader = new AliRawReaderDate((void*)event);
- //rawReader->RequireHeader(kFALSE);
-
- //T0 event
- Int_t meantime = 0;
- AliT0RawReader *rawReaderT0 = new AliT0RawReader(rawReader,kTRUE);
- if (!rawReaderT0->Next()) {
- printf("T0: no raw data found!\n");
- }
- else {
- /*
- Int_t allData[105][5];
- for (Int_t i=0; i<105; i++) {
- allData[i][0]=rawReaderT0->GetData(i,0);
- }
- meantime = allData[49][0];
- */
- meantime = rawReaderT0->GetData(49,0);
- // printf("time zero (ns) = %i (%f) \n", meantime, (meantime*24.4-200)*1E-3); // debugging purpose
- }
-
- delete rawReaderT0;
- rawReaderT0 = 0x0;
- rawReader->Reset();
-
- //TOF event
- Int_t dummy = -1;
- Int_t Volume[5];
- AliTOFHitData *HitData;
- AliTOFHitDataBuffer *DataBuffer;
- AliTOFHitDataBuffer *PackedDataBuffer;
- AliTOFRawStream *rawStreamTOF = new AliTOFRawStream(rawReader);
- // rawReader->ReadHeader();
- rawStreamTOF->ResetBuffers();
- rawStreamTOF->DecodeDDL(0, AliDAQ::NumberOfDdls("TOF") - 1,0);
- Int_t nPDBEntriesToT = 0;
- Int_t nDBEntriesToT = 0;
- for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls("TOF"); iDDL++){
-
- /* read decoded data */
- DataBuffer = rawStreamTOF->GetDataBuffer(iDDL);
- PackedDataBuffer = rawStreamTOF->GetPackedDataBuffer(iDDL);
-
- /* get buffer entries */
- Int_t nDBEntries = DataBuffer->GetEntries();
- Int_t nPDBEntries = PackedDataBuffer->GetEntries();
- nPDBEntriesToT+=nPDBEntries;
- nDBEntriesToT+=nDBEntries;
-
- //for (Int_t iHit = 0; iHit < nDBEntries; iHit++){
- // HitData = DataBuffer->GetHit(iHit);
- /* store volume information */
- // rawStreamTOF->EquipmentId2VolumeId(HitData, Volume);
- //}
- /* reset buffer */
- DataBuffer->Reset();
-
- /* read data buffer hits */
- for (Int_t iHit = 0; iHit < nPDBEntries; iHit++){
- HitData = PackedDataBuffer->GetHit(iHit);
- /* add volume information */
- HitData->SetDDLID(iDDL);
- rawStreamTOF->EquipmentId2VolumeId(HitData, Volume);
- if (Volume[0]==-1 ||
- Volume[1]==-1 ||
- Volume[2]==-1 ||
- Volume[3]==-1 ||
- Volume[4]==-1) continue;
- else {
- dummy = Volume[3];
- Volume[3] = Volume[4];
- Volume[4] = dummy;
- Int_t tof = (Int_t)((Double_t)HitData->GetTime()*1E3/AliTOFGeometry::TdcBinWidth());
- Int_t index = geom->GetIndex(Volume);
- Float_t pos[3];
- geom->GetPosPar(Volume,pos);
- Float_t texp=TMath::Sqrt(pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2])/c*1E9; //expected time in ns
- Float_t texpBin=(texp*1E3-32)/AliTOFGeometry::TdcBinWidth(); //expected time in number of TDC bin
- Int_t deltabin = tof-TMath::Nint(texpBin); //to be used with real data; rounding expected time to Int_t
- htofPartial->Fill(index,deltabin); //channel index start from 0, bin index from 1
- //debugging printings
- //printf("sector %i, plate %i, strip %i, padz %i, padx %i \n",Volume[0],Volume[1],Volume[2],Volume[3],Volume[4]);
- //printf("pos x = %f, pos y = %f, pos z = %f \n",pos[0],pos[1],pos[2]);
- //printf ("expected time = %f (ns)\n",texp);
- //printf ("expected time bin = %f (TDC bin)\n",texpBin);
- //printf ("measured time bin = %i (TDC bin) with %f (ns) and ACQ bit = %i \n",tof, HitData->GetTime(), HitData->GetACQ());
- // printf("index = %i, deltabin = %i , filling index = %i, and bin = % i\n",index, deltabin, index, deltabin);
-
- }
- /* reset buffer */
- PackedDataBuffer->Reset();
- }
- }
- //printf(" Packed Hit Buffer Entries = %i \n",nPDBEntriesToT);
- //printf(" Hit Buffer Entries = %i \n",nDBEntriesToT);
-
- delete rawStreamTOF;
- rawStreamTOF = 0x0;
-
- delete rawReader;
- rawReader = 0x0;
- }
+ /*
+ * HIT MANIPULATION
+ */
+
+ /* loop over DDLs */
+ for (Int_t iddl = 0; iddl < AliDAQ::NumberOfDdls("TOF"); iddl++) {
+ /* get packed-data buffer */
+ pdb = rawStream->GetPackedDataBuffer(iddl);
+ nhits = pdb->GetEntries();
+ /* loop over hits in buffer */
+ for (Int_t ihit = 0; ihit < nhits; ihit++) {
+ /* get hit */
+ hit = pdb->GetHit(ihit);
+ /* get channel info */
+ ddl = iddl;
+ slot = hit->GetSlotID();
+ trm = slot - 3;
+ chain = hit->GetChain();
+ tdc = hit->GetTDC();
+ channel = hit->GetChan();
+ /* get index */
+ rawStream->EquipmentId2VolumeId(ddl, slot, chain, tdc, channel, det);
+ dummy = det[4];
+ det[4] = det[3];
+ det[3] = dummy;
+ /* check valid index */
+ if (det[0] < 0 || det[0] > 17 ||
+ det[1] < 0 || det[1] > 5 ||
+ det[2] < 0 || det[2] > 18 ||
+ det[3] < 0 || det[3] > 1 ||
+ det[4] < 0 || det[4] > 47) continue;
+ index = AliTOFGeometry::GetIndex(det);
+
+ /* switch event type */
+ switch (event->eventType) {
+
+ /*
+ * PHYSICS EVENT
+ */
+
+ case PHYSICS_EVENT:
+ /* check noise flag */
+ if (noiseFlag[index]) continue;
+ /* increment number of channel hits and total hits */
+ nChHits[index]++;
+ totHits++;
+ /* get signal info */
+ timebin = hit->GetTimeBin();
+ totbin = hit->GetTOTBin();
+ deltaBC = hit->GetDeltaBunchID();
+ l0l1latency = hit->GetL0L1Latency();
+ /* set hit field data */
+ hitField->SetIndex(index);
+ hitField->SetTimeBin(timebin);
+ hitField->SetTOTBin(totbin);
+ hitField->SetDeltaBC(deltaBC);
+ hitField->SetL0L1Latency(l0l1latency);
+ /* fill temp tree */
+ tempTree->Fill();
+ break;
+
+ /*
+ * CALIBRATION EVENT
+ */
+
+ case CALIBRATION_EVENT:
+ /* fill calib hit histo */
+ hCalibHit->Fill(index);
+ break;
+
+ } /* end of switch event type */
+ } /* end of loop over hits in buffer */
+ } /* end of loop over DDLs */
- /* free resources */
+ /* delete raw reader */
+ delete rawReader;
+ /* free event */
free(event);
- /* exit when last event received, no need to wait for TERM signal */
- if (eventT==END_OF_RUN) {
- printf("EOR event detected\n");
- break;
- }
- }
-
- delete geom;
- geom = 0x0;
-
- //write the Run level file
- TFile * fileRun = new TFile (FILE_RUN,"RECREATE");
- htofPartial->Write();
- fileRun->Close();
-
- //write the Total file
- TH2S *htoftot = 0x0;
- TFile * filetot = 0x0;
- Bool_t isThere=kFALSE;
- const char *dirname = "./";
- TString filename = FILE_TOTAL;
- if((gSystem->FindFile(dirname,filename))!=NULL){
- isThere=kTRUE;
- printf("%s found \n",FILE_TOTAL);
- }
- if(isThere){
-
- TFile * filetot1 = new TFile (FILE_TOTAL,"READ");
- //look for the file
- if (!filetot1->IsZombie()){
- printf("updating file %s \n",FILE_TOTAL);
- TIter next(filetot1->GetListOfKeys());
- TKey *key;
- //look for the histogram
- while ((key=(TKey*)next())){
- const char * namekey = key->GetName();
- if (strcmp(namekey,"htoftot")==0){
- printf(" histo found \n");
- htoftot = (TH2S*) filetot1->Get("htoftot");
- htoftot->AddDirectory(0);
- htoftot->Add(htofPartial);
- break;
- }
- }
- }
- filetot1->Close();
- delete filetot1;
- filetot1=0x0;
- }
- else {
- printf(" no %s file found \n",FILE_TOTAL);
- htoftot = new TH2S(*htofPartial);
- htoftot->SetName("htoftot");
- htoftot->AddDirectory(0);
- }
+ } /* end of loop over events */
- filetot = new TFile (FILE_TOTAL,"RECREATE");
- filetot->cd();
- htoftot->Write();
- filetot->Close();
+ /* final noise check */
+ noiseHitThreshold = noiseThreshold * nPhysicsEvents;
+ printf("final noise check after %d events: threshold is %f hits\n", nPhysicsEvents, noiseHitThreshold);
+ /* loop over all channels */
+ for (Int_t ich = 0; ich < nChannels; ich++) {
+ /* check */
+ if (nChHits[ich] < minNoiseHits || noiseFlag[ich] || nChHits[ich] < noiseHitThreshold) continue;
+ printf("channel %d tagged as noisy (%d hits): disabled\n", ich, nChHits[ich]);
+ noiseFlag[ich] = kTRUE;
+ totHits -= nChHits[ich];
+ } /* end of loop over all channels */
- delete fileRun;
- delete filetot;
- delete htofPartial;
- delete htoftot;
-
- fileRun = 0x0;
- filetot = 0x0;
- htofPartial = 0x0;
- htoftot = 0x0;
-
- /* write report */
- printf("Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);
-
- status=0;
+ /* copy hits into output tree from temp tree */
+ printf("copy hits from temporary tree into output tree\n");
+ printf("temporary tree contains %d hits\n", (Int_t)tempTree->GetEntries());
+ for (Int_t ihit = 0; ihit < tempTree->GetEntries(); ihit++) {
+ /* get entry */
+ tempTree->GetEntry(ihit);
+ /* check noise flag */
+ if (noiseFlag[hitField->GetIndex()]) continue;
+ /* fill output tree */
+ outTree->Fill();
+ } /* end of copy hits into output tree from temp tree */
+ printf("output tree contains %d hits\n", (Int_t)outTree->GetEntries());
+ /* write output tree on HITS file */
+ fileOutHits->cd();
+ outTree->Write();
+ fileOutHits->Close();
/* export file to FXS */
- if (daqDA_FES_storeFile(FILE_RUN, FILE_RUN)) {
- status=-2;
- }
- if (daqDA_FES_storeFile(FILE_TOTAL, FILE_TOTAL)) {
- status=-2;
- }
+ if (daqDA_FES_storeFile(FILE_HITS, "HITS"))
+ return -2;
+ /* scale calib hit histo by number of calib events */
+ printf("found %d calibration events\n", nCalibEvents);
+ hCalibHit->Sumw2();
+ if (nCalibEvents > 0)
+ hCalibHit->Scale(1. / nCalibEvents);
- return status;
-}
+ /* write calib hit histo on CALIB file */
+ fileOutCalib->cd();
+ hCalibHit->Write();
+ fileOutCalib->Close();
+ /* export file to FXS */
+ if (daqDA_FES_storeFile(FILE_CALIB, "CALIB"))
+ return -2;
+ return 0;
+}