//*-- AUTHOR : J.Kempter //*-- Modified : //_HADES_CLASS_DESCRIPTION /////////////////////////////////////////////////////////////////////////////// // // HMdcOffset // // Defines the offset parameter for MDC calibration. Uses HMdcCalParRaw container // as input/output for calibration data // /////////////////////////////////////////////////////////////////////////////// using namespace std; #include #include #include #include #include #include #include #include #include #include #include #include #include "heventheader.h" #include "hmdcoffset.h" #include "hmdcdef.h" #include "hmdctrackddef.h" #include "hmdcsizescells.h" #include "hmdcraw.h" #include "hmdcclus.h" #include "hdebug.h" #include "hades.h" #include "hiterator.h" #include "hruntimedb.h" #include "hspectrometer.h" #include "hmdcdetector.h" #include "hdetector.h" #include "hevent.h" #include "hcategory.h" #include "hlocation.h" #include "hmdccal1.h" #include "hmdclookupgeom.h" #include "hmdclookupraw.h" #include "hmdccalpar.h" #include "hmdccalparraw.h" #include "hmdclookupraw.h" #include "hstarthit.h" #include "hstartdef.h" #include "hmdctimecut.h" ClassImp(HMdcOffset) const Int_t HMdcOffset::nbin = 2048; const Int_t HMdcOffset::nbinp1 = HMdcOffset::nbin+1; const Int_t HMdcOffset::nbinm1 = HMdcOffset::nbin-1; const Int_t HMdcOffset::nSubEvents = (6*192)*3; HMdcOffset::HMdcOffset(void) { setDefault(); initVariables(); //initMemory(); } HMdcOffset::HMdcOffset(Text_t* name,Text_t* title) : HReconstructor(name,title) { setDefault(); initVariables(); //initMemory(); } HMdcOffset::~HMdcOffset(void) { // Destructor. if (iter) delete iter; if (iter_start) delete iter_start; if (iter_clus) delete iter_clus; if (fNameAsciiOffset) delete fNameAsciiOffset; if (fNameRootOffset) delete fNameRootOffset; if (hreverse) delete[] hreverse; iter = NULL; iter_start= NULL; iter_clus = NULL; } void HMdcOffset::initVariables() { // pointer to iterators and categories rawCat =0; hitStartCat =0; clusCat =0; iter =0; iter_start =0; iter_clus =0; locraw.set(4,0,0,0,0); // switch options isPulserFile =kFALSE; noStart =kFALSE; useTimeCuts =kTRUE; useClusters =kTRUE; useWireOffset=kTRUE; useTof =kFALSE; debug =kFALSE; // pointers to fileds and hists hreverse = (MyField*) new MyField; hint =0; hinv =0; // container pointers calparraw =0; lookupgeom =0; timecut =0; sizescells =0; // constants signalspeed=0.004; // [ns/mm] // varables in finalize validRange =1000.; meanhOffset =0; myoffset=0; myerror=0; // counters eventcounter =0; skipcounter =0; nSkipEvents =0; // output file names fNameAsciiOffset =0; fNameRootOffset =0; ferrorlog=0; offsetTuple =0; offsetPulserTuple=0; // fit variables yequalzero =0; crosspointX =0; fitpar0 =0; fitpar0error =0; fitpar1 =0; fitpar1error =0; fitparNoise0 =0; fitparNoise0error=0; fitparNoise1 =0; fitparNoise1error=0; totalsigma =0; fitGaussMean =0; fitGaussSigma =0; } void HMdcOffset::setDefault() { // Sets the the default values for the fits. setNoise(100, 50); setThreshold(0.15, 0.5); setRangeGauss(50); } void HMdcOffset::setOutputAscii(Char_t *c) { // Sets ascii output of HMdcOffset for debugging output. if (fNameAsciiOffset) delete fNameAsciiOffset; fNameAsciiOffset = new Char_t[strlen(c)+1]; strcpy(fNameAsciiOffset, c); } void HMdcOffset::setOutputRoot(Char_t *c) { // Sets rootfile output of HMdcOffset where all created histograms were written. // if (fNameRootOffset) delete fNameRootOffset; fNameRootOffset = new Char_t[strlen(c)+1]; strcpy(fNameRootOffset, c); } void HMdcOffset::setUseTof(TString filename) { // Retrieves TF1's for min tof substraction from root file // and switches the usesage of tof substraction kTRUE. if (filename.CompareTo("")==0) { // check for empty string useTof=kFALSE; Warning("setUseTof()","Empty String received for inputfile name of tof parameters!"); exit(1); } else { // if string is not empty TFile* inp=new TFile(filename,"READ"); if(inp==0) { // if file does not exist Warning("setUseTof()","Input file not existent!"); exit(1); } else { // if file exists cout<<"HMdcOffset::setUseTof(): Reading from "<Get(fitname); if(toffunc[mdc][lay]==0) { // if fit object has not been found in file Warning("setUseTof()","Error in reading input file!"); exit(1); } } } useTof=kTRUE; } } } void HMdcOffset::printStatus() { printf("**************** HMdcOffset ***********************\n"); printf("* ACTUAL SETTINGS *\n"); if(useTimeCuts) { printf("* TIME CUTS are used *\n"); } if(!useTimeCuts) { printf("* NO TIME CUTS are used *\n"); } if(useClusters) { printf("* TIMES FILLED FROM CLUSTERS *\n"); } if(!useClusters) { printf("* TIMES FILLED FROM RAW *\n"); } if(useWireOffset&&useClusters) { printf("* TIME OF SIGNAL ON WIRE SUBTRACTED *\n"); } if(!useWireOffset) { printf("* TIME OF SIGNAL ON WIRE NOT SUBTRACTED *\n"); } if(useTof) { printf("* MINIMUM TOF WILL BE SUBSTRACTED *\n"); } if(!useTof) { printf("* MINIMUM TOF WILL NOT BE SUBSTRACTED *\n"); } if(isPulserFile) { printf("* Mode set to PULSER FILE *\n"); } if(!isPulserFile) { printf("* Mode set to REAL DATA FILE *\n"); } if(!noStart) { printf("* START TIMES are used *\n"); } if(noStart) { printf("* NO START TIMES are used *\n"); } printf("* SIGNALSPEED = %5.3f [ns/mm] *\n",signalspeed); printf("* VALID OFFSET RANGE = %5.1f *\n",validRange); printf("* NOISE OFFSET = %4i *\n",offsetfitNoise); printf("* NOISE WIDTH = %4i *\n",widthfitNoise); printf("* MIN Threshold = %1.2f MAX Threshold = %1.2f *\n",minfitthreshold,maxfitthreshold); printf("* Range GAUSS FIT = %4i *\n",rangeGauss); printf("**************** HMdcOffset ***********************\n"); } Bool_t HMdcOffset::init(void) { // Inits HMdcOffset and the needed HMdcCalParRaw, if this container does not exists if(!noStart) { hitStartCat=gHades->getCurrentEvent()->getCategory(catStartHit); //???? if (!hitStartCat) { Error("init()","NO START HIT CATEGORY IN INPUT!"); return kFALSE; } else iter_start=(HIterator *)hitStartCat->MakeIterator("native"); } if(useClusters) { clusCat=gHades->getCurrentEvent()->getCategory(catMdcClus); //???? if (!clusCat) { Error("init()","NO CLUS CATEGORY IN INPUT!"); return kFALSE; } else iter_clus=(HIterator *)clusCat->MakeIterator("native"); lookupraw =(HMdcLookupRaw*) gHades->getRuntimeDb()->getContainer("MdcLookupRaw"); if(useWireOffset) { sizescells=HMdcSizesCells::getExObject(); if(!sizescells) { Error("init()","NO HMDCSIZESCELLS CONTAINER IN INPUT!"); return kFALSE; } } } calparraw =(HMdcCalParRaw*) gHades->getRuntimeDb()->getContainer("MdcCalParRaw"); timecut =(HMdcTimeCut*) gHades->getRuntimeDb()->getContainer("MdcTimeCut"); lookupgeom=(HMdcLookupGeom*)gHades->getRuntimeDb()->getContainer("MdcLookupGeom"); rawCat=gHades->getCurrentEvent()->getCategory(catMdcRaw); if (!rawCat) { Error("init()","NO MDC RAW CATEGORY IN INPUT!"); return kFALSE; } else { // creates an iterator which loops over all fired cells iter=(HIterator *)rawCat->MakeIterator(); } fActive=kTRUE; eventcounter=0; skipcounter=0; printStatus(); return kTRUE; } Bool_t HMdcOffset::reinit(void) { // cout<<"skipcount "<TDirectory::Cd("hinv"); sprintf(tmp, "%s%i%s%i%s%02i%s%02i%s", "hinv[",s,"][",m,"][",l,"][",c,"]"); hinv = new MyHist(tmp, title, nbin,-nbin+0.5,0.5); //inverted hist. file->TDirectory::Cd("../hint"); sprintf(tmp, "%s%i%s%i%s%02i%s%02i%s", "hint[",s,"][",m,"][",l,"][",c,"]"); hint = new MyHist(tmp, title, nbin,-nbin+0.5,0.5); // integrated hist. file->TDirectory::Cd(".."); } void HMdcOffset::createHist_2D(Int_t s, Int_t m) { // Histograms for inverted Time1 and integrated Time1 per Tdc-Channel are created // in a subdirectory structure. static Char_t title[50], tmp[30]; for(Int_t mb=0;mb<16;mb++) { sprintf(title,"%s%i%s%i%s%i","Sector ",s," Module ",m," Mbo ", mb); sprintf(tmp, "%s%i%s%i%s%02i%s", "htime1_mbo[",s,"][",m,"][",mb,"]"); htime1_mbo[mb] = new TH2F(tmp, title,700,-200,500,96,1,97); //hist time vers tdc. } for(Int_t lay=0;lay<6;lay++) { sprintf(title,"%s%i%s%i%s%i","Sector ",s," Module ",m," Lay ", lay); sprintf(tmp, "%s%i%s%i%s%02i%s", "htime1_lay[",s,"][",m,"][",lay,"]"); htime1_lay[lay] = new TH2F(tmp, title,700,-200,500,210,1,211); //hist time vers tdc. } for(Int_t lay=0;lay<6;lay++) { sprintf(title,"%s%i%s%i%s%i","Sector ",s," Module ",m," Lay ", lay); sprintf(tmp, "%s%i%s%i%s%02i%s", "htime1_lay_inv_norm[",s,"][",m,"][",lay,"]"); htime1_lay_inv_norm[lay] = new TH2F(tmp, title,700,-200,500,210,1,211); //hist time vers tdc. } for(Int_t lay=0;lay<6;lay++) { sprintf(title,"%s%i%s%i%s%i","Sector ",s," Module ",m," Lay ", lay); sprintf(tmp, "%s%i%s%i%s%02i%s", "htime1_lay_int[",s,"][",m,"][",lay,"]"); htime1_lay_int[lay] = new TH2F(tmp, title,700,-200,500,210,1,211); //hist time vers tdc. } for(Int_t lay=0;lay<6;lay++) { sprintf(title,"%s%i%s%i%s%i","Sector ",s," Module ",m," Lay ", lay); sprintf(tmp, "%s%i%s%i%s%02i%s", "htime1_lay_int_norm[",s,"][",m,"][",lay,"]"); htime1_lay_int_norm[lay] = new TH2F(tmp, title,700,-200,500,210,1,211); //hist time vers tdc. } } void HMdcOffset::deleteHist() { // Created histograms are deleted delete hinv; delete hint; } void HMdcOffset::deleteHist_2D() { // Created histograms are deleted for(Int_t mb=0;mb<16;mb++) { delete htime1_mbo[mb]; } for(Int_t lay=0;lay<6;lay++) { delete htime1_lay[lay]; delete htime1_lay_inv_norm[lay]; delete htime1_lay_int[lay]; delete htime1_lay_int_norm[lay]; } } void HMdcOffset::fillHist(Int_t s, Int_t m, Int_t l, Int_t c) { // Histograms for inverted Time1 and integrated Time1 per Tdc-Channel are filled hint->SetBinContent(1,(Double_t)(*hreverse)[s][m][l][c][0]); hinv->SetBinContent(1,(Double_t)(*hreverse)[s][m][l][c][0]); for(Int_t k=2; kSetBinContent(k,(Double_t)(*hreverse)[s][m][l][c][k-1]); hint->SetBinContent(k,(hint->GetBinContent(k-1)+hinv->GetBinContent(k))); } integral[s][m][l][c]=(Int_t)hint->GetBinContent(nbin-2); } void HMdcOffset::fillHist_2D(Int_t s, Int_t m, Int_t l, Int_t c) { // Histograms for Time1 vers Tdc-Channel and cell are filled HMdcLookupChan& chan=(*lookupgeom)[s][m][l][c]; Int_t layer= chan.getNLayer(); Int_t cell= chan.getNCell(); Int_t myoffbin=(Int_t)(2048-offsets[s][m][l][c]); // convert offset x to offset bin Float_t temp; for(Int_t k=1; k-200) // check if bin in range { Int_t mybin=200+k-myoffbin; temp=htime1_mbo[l]->GetCellContent(mybin,c+1); htime1_mbo[l] ->SetCellContent(mybin,c+1 ,hinv->GetBinContent(k)+temp); temp=htime1_lay[layer]->GetCellContent(mybin,cell+1); htime1_lay[layer]->SetCellContent(mybin,cell+1,hinv->GetBinContent(k)+temp); temp=htime1_lay_int[layer]->GetCellContent(mybin,cell+1); htime1_lay_int[layer]->SetCellContent(mybin,cell+1,hint->GetBinContent(k)+temp); temp=htime1_lay_inv_norm[layer]->GetCellContent(mybin,cell+1); htime1_lay_inv_norm[layer]->SetCellContent(mybin,cell+1,hinv->GetBinContent(k)+temp); temp=htime1_lay_int_norm[layer]->GetCellContent(mybin,cell+1); htime1_lay_int_norm[layer]->SetCellContent(mybin,cell+1,hint->GetBinContent(k)+temp); } } Float_t max_inv=hinv->GetMaximum(); Float_t max_int=hint->GetMaximum(); for(Int_t k=1; kGetCellContent(k,cell+1); htime1_lay_inv_norm[layer]->SetCellContent(k,cell+1,temp/max_inv); } if(max_int!=0) { temp=htime1_lay_int_norm[layer]->GetCellContent(k,cell+1); htime1_lay_int_norm[layer]->SetCellContent(k,cell+1,temp/max_int); } } } Int_t HMdcOffset::fitHist(Int_t s, Int_t m, Int_t l, Int_t c) { // The offset is calculated from two linear fits. Some pictures of the fitted histograms // can be found on Begin_Html MDC calibration pageEnd_Html . // The first linear fit (red) is done to find the rising edge of the integrated spectra. // The second linear fit (blue) is done to substract the noise. // The ranges for both fits can be set through the functions setNoise()(x-range) for the // second fit (default values: 100,50) and setThreshold()(y-range) for the first fit // (default values :0.15,0.50). The y-range is calculated by the percentage of the maximum // height of the spectra. // The offset ist calculated from the intersection point of both linear fits. // The sigma of the offset is calculated from the sigmas of the two linear fits. // // If the analyzed file is a pulser file for external calibration a gaussian fit is done. // To set this fit the function setPulserFile() has to be used in the macro. The range of // the fit is set through the function setRangeGauss()(default value: 50) around the maximum. // The mean and sigma of the fit is written to the ascii debugging output. // The hist is checked for multiple peaks.The peaks which have been found are written to an array. fitGaussMean = 0; fitGaussSigma = 0; fitpar0 =0; fitpar0error=0; fitpar1 =0; fitpar1error=0; fitparNoise0 =0; fitparNoise1 =0; fitparNoise0error=0; fitparNoise1error=0; totalsigma=0; yequalzero=0; crosspointX=0; //----------------------------------------------------------- // if hist is empty do nothing if(hint->Integral()==0) { if(debug)cout<GetMinimum()<0) { cout<<" "<GetBinContent(nbinm1-1); // setting y thresholds for fitting Float_t ymaxfit=maxfitthreshold*hint->GetBinContent(nbinm1-1); // relative to maximum y-value while (hint->GetBinContent(--xmaxfitbin) > ymaxfit && xmaxfitbin); // find to ymaxfit corresponding bin //----------------------------------------------------------- //----------------------------------------------------------- // if no match for the upper fit range has been found in // the desired Y range if (!xmaxfitbin) { if(debug)cout<Integral()<GetBinContent(--xminfitbin) > yminfit && xminfitbin); // find to yminfit corresponding bin //----------------------------------------------------------- //----------------------------------------------------------- // if no match for the lower fit range has been found in // the desired Y range if (!xminfitbin) { if(debug)cout<Integral()<Integral()<GetBinCenter(xminfitbin),hint->GetBinCenter(xmaxfitbin)); // call fit function poynom 1.order in x-range hint->Fit("fitsignal","RNQ"); fitpar0 =0; fitpar0error=0; fitpar1 =0; fitpar1error=0; fitpar0 =f->GetParameter(0); // get fitparameters fitpar0error=f->GetParError (0); fitpar1 =f->GetParameter(1); //(f1->GetParameter(1)<0.000001)?-1:(f1->GetParameter(1)); fitpar1error=f->GetParError (1); // y=fitpar[1]* x + fitpar[0] //----------------------------------------------------------- //----------------------------------------------------------- // if result of fit is nan or inf. if(TMath::Finite(f->GetParameter(0))==0 || TMath::Finite(f->GetParameter(1))==0 ) { // bullshit !! if(debug)cout<Integral() <<" xminbin "<GetParameter(0) <<" fitpar1 "<GetParameter(1) <Integral() <<" xminbin "< nbin) { if(debug)cout<Integral() <<" -yequalzero "<<-yequalzero <<" xminbin "<Integral(hint->FindBin(yequalzero-(offsetfitNoise+widthfitNoise)), hint->FindBin(yequalzero-offsetfitNoise))<10 ) { // almost no counts in range of fit! if(debug)cout<Integral() <<" -yequalzero "<<-yequalzero <<" minbinNoise "<FindBin(yequalzero-(offsetfitNoise+widthfitNoise)) <<" maxbinNoise "<FindBin(yequalzero-offsetfitNoise) <Fit("fitnoise","RNQ"); fitparNoise0 =0; fitparNoise1 =0; fitparNoise0error=0; fitparNoise1error=0; fitparNoise0 =f->GetParameter(0); // get fitparameters fitparNoise1 =f->GetParameter(1); fitparNoise0error=f->GetParError (0); // get fitparameters fitparNoise1error=f->GetParError (1); //----------------------------------------------------------- //----------------------------------------------------------- // if result of fit is nan or inf. // if so yequalzero is taken as offset if(TMath::Finite(f->GetParameter(0))==0 || TMath::Finite(f->GetParameter(1))==0 ) { // bullshit !! if(debug)cout<Integral() <<" -yequalzero "<<-yequalzero <<" minbinNoise "<FindBin(yequalzero-(offsetfitNoise+widthfitNoise)) <<" maxbinNoise "<FindBin(yequalzero-offsetfitNoise) <<" fitparNoise0 "<GetParameter(0) <<" fitparNoise1 "<GetParameter(1) <Integral() <<" -yequalzero "<<-yequalzero <<" minbinNoise "<FindBin(yequalzero-(offsetfitNoise+widthfitNoise)) <<" maxbinNoise "<FindBin(yequalzero-offsetfitNoise) <<" fitpar0 "<GetParameter(0) <<" fitparNoise1 "<GetParameter(1) <nbinm1) { if(debug)cout<Integral() <<" -yequalzero "<<-yequalzero <<" crosspaintX "<FindBin(yequalzero-(offsetfitNoise+widthfitNoise)) <<" maxbinNoise "<FindBin(yequalzero-offsetfitNoise) <<" fitpar0 "<GetParameter(0) <<" fitparNoise1 "<GetParameter(1) <-100000) { fitslope1[s][m][l][c]=fitpar1; } else { fitslope1[s][m][l][c]=0; } if(fitparNoise1<100000&&fitpar1>-100000) { fitslope2[s][m][l][c]=fitparNoise1; } else { fitslope2[s][m][l][c]=0; } if (!isPulserFile) return 0; //f = new TF1("f3","gaus", -crosspointX-rangeGauss, -crosspointX+rangeGauss); // If there are more than 1 peak only the most prominant is fitted Float_t localmax=(2048-(hinv->GetMaximumBin())); f = new TF1("f3","gaus",-localmax-rangeGauss, -crosspointX+rangeGauss); hinv->Fit("f3","RNQ"); fitGaussMean =f->GetParameter(1); //mean fitGaussSigma=f->GetParameter(2); //sigma findMultiplePeaks(s,m,l,c); delete f; // FIXME: Error handling for gauss fit ??? return 0; } void HMdcOffset::findMultiplePeaks(Int_t s,Int_t m,Int_t l,Int_t c) { for(Int_t j=0;j<2047;j++) { htime1temp->SetBinContent(j,hinv->GetBinContent(j));// copy hinv to temp hist } htime1temp->Smooth(10);// make it smooth Char_t address[50]; Float_t binlowold[5]; Float_t binhighold[5]; Float_t binlow[5]; Float_t binhigh[5]; Int_t binmax[5]; Float_t offout[5]; Float_t max=0; Float_t min=0; Float_t threshold=0.05; for(Int_t j=0;j<5;j++)// reset helper arrays { binlowold[j]=0; binhighold[j]=0; binlow[j]=0; binhigh[j]=0; binmax[j]=0; offout[j]=0; } max=min=0; max=htime1temp->GetMaximum(); // get max height min=threshold*max; Int_t count=0; for(Int_t bin=0;bin<2047;bin++) { if(count<5) { binlow [count]=htime1temp->GetBinContent(bin); binhigh[count]=htime1temp->GetBinContent(bin+1); if(bin>40 && binlow[count]>20 // skip the first 40 tdc bins and take into account only if > 20 counts && fabs(binhigh[count]-binlow[count])>1 && (binhighold[count]-binlowold[count]>0) && (binhigh[count]-binlow[count]<0) ) // if zero was crossed { binmax[count]=bin; count++; } if(count<5) { binlowold [count]=binlow [count]; binhighold[count]=binhigh[count]; } else { cout<<"MORE THAN 5 PEAKS!"<1) { cout<<" "<0) { offsetpulser[s][m][l][c][j]=(2048-binmax[j]); } else { offsetpulser[s][m][l][c][j]=0; } } } void HMdcOffset::writeAscii(ofstream &fout, Int_t s, Int_t m, Int_t l, Int_t c) { // The adresses of the channel(sector,module,mbo,tdc),offset, two fitparameters for the // two linear fits, the sigma of the offset ,offset and the integral(number of entries for this channel) // are written to the ascii debugging output.In the case of an pulser file (external calibration) // the mean and the sigma of the gaussian fit are also written to the output. if (isPulserFile) fout << setw(3) << s << " " << setw(4) << m << " " << setw(4) << l << " " << setw(5) << c << " " << setw(10) << -yequalzero << " " << setw(10) << yequalzero << " " << setw(10) << crosspointX << " " << setw(15) << -fitGaussMean << " " << setw(15) << fitGaussSigma << " " << setw(15) << fitpar0 << " " << setw(15) << fitpar1 << " " << setw(15) << fitparNoise0 << " " << setw(15) << fitparNoise1 << " " << setw(15) << totalsigma << " " << setw(10) << integral[s][m][l][c] << endl; else fout << setw(3) << s << " " << setw(4) << m << " " << setw(4) << l << " " << setw(5) << c << " " << setw(10) << -yequalzero << " " << setw(10) << crosspointX << " " << setw(15) << fitpar0 << " " << setw(15) << fitpar1 << " " << setw(15) << fitparNoise0 << " " << setw(15) << fitparNoise1 << " " << setw(15) << totalsigma << " " << setw(10) << integral[s][m][l][c] << endl; } void HMdcOffset::writeHist(TFile* file) { // All created histograms are written to a rootfile.The file is structured for sector,module,mbo. file->TDirectory::Cd("hinv"); hinv->Write(); file->TDirectory::Cd("../hint"); hint->Write(); file->TDirectory::Cd(".."); } void HMdcOffset::writeHist_2D() { // All created histograms are written to a rootfile. for(Int_t mb=0;mb<16;mb++) { htime1_mbo[mb]->SetEntries(1); htime1_mbo[mb]->SetOption("colz"); htime1_mbo[mb]->Write(); } for(Int_t lay=0;lay<6;lay++) { htime1_lay[lay]->SetEntries(1); htime1_lay[lay]->SetOption("colz"); htime1_lay[lay]->Write(); htime1_lay_inv_norm[lay]->SetEntries(1); htime1_lay_inv_norm[lay]->SetOption("colz"); htime1_lay_inv_norm[lay]->Write(); htime1_lay_int[lay]->SetEntries(1); htime1_lay_int[lay]->SetOption("colz"); htime1_lay_int[lay]->Write(); htime1_lay_int_norm[lay]->SetEntries(1); htime1_lay_int_norm[lay]->SetOption("colz"); htime1_lay_int_norm[lay]->Write(); } } ofstream *HMdcOffset::openAsciiFile() { // Opens the ascii debugging output and writes the headerline. ofstream *fout=NULL; if (fNameAsciiOffset) fout = new ofstream(fNameAsciiOffset, ios::out); if (fout) // changed *fout if (isPulserFile) { *fout //<< "Layer Cell crosspoint" << endl; << setw(3) << "s" << " " << setw(4) << "mo" << " " << setw(4) << "mb" << " " << setw(5) << "t" << " " << setw(10) << "yequalzero" << " " << setw(10) << "Offset" << " " << setw(15) << "GaussMean" << " " << setw(15) << "GaussSigma" << " " << setw(15) << "fitpar0" << " " << setw(15) << "fitpar1" << " " << setw(15) << "fitparNoise0" << " " << setw(15) << "fitparNoise1" << " " << setw(15) << "totalsigma" << " " << setw(10) << "Integral" << " "<< endl; *fout << setw(14) << "[MdcCalParRaw]" <Fill(s,mo,mb,t, chan.getNLayer(), chan.getNCell(), (*calparraw)[s][mo][mb][t].getSlope(), (*calparraw)[s][mo][mb][t].getSlopeErr(), offsets[s][mo][mb][t], offsetErr[s][mo][mb][t], integral[s][mo][mb][t], offset1[s][mo][mb][t], fitslope1[s][mo][mb][t], fitslope2[s][mo][mb][t]); offsetPulserTuple->Fill(s,mo,mb,t, chan.getNLayer(), chan.getNCell(), offsets[s][mo][mb][t], offsetErr[s][mo][mb][t], integral[s][mo][mb][t], offsetpulser[s][mo][mb][t][0], offsetpulser[s][mo][mb][t][1], offsetpulser[s][mo][mb][t][2], offsetpulser[s][mo][mb][t][3], offsetpulser[s][mo][mb][t][4]); } void HMdcOffset::fillArrays(TH1F *hOffset, Int_t s,Int_t mo,Int_t mb,Int_t t) { if(!isPulserFile) { hOffset->Fill(crosspointX); offsets[s][mo][mb][t]=crosspointX; offsetErr[s][mo][mb][t]=totalsigma; offset1[s][mo][mb][t]=-yequalzero; } else { hOffset->Fill(fitGaussMean); offsets[s][mo][mb][t]=-fitGaussMean; offsetErr[s][mo][mb][t]=fitGaussSigma; offset1[s][mo][mb][t]=-yequalzero; } } void HMdcOffset::fillCalParRaw(TH1F *hOffsetcorr, Int_t s,Int_t mo,Int_t mb,Int_t t) { // fills CalParRaw with offsets, offseterrors and Methods // Checks if offset is in valid range arround mean value of offsets. // If it is out of range the value is replaced by the mean value. // Not connected channels are marked with -7. myoffset=offsets [s][mo][mb][t]; myerror =offsetErr[s][mo][mb][t]; HMdcLookupChan& chan=(*lookupgeom)[s][mo][mb][t]; Int_t connected=0; connected=chan.getNCell(); if(!myoffset){myoffset=0;} if(myoffset>=0) // all offsets where no error showed up { if((myoffsetmeanhOffset+validRange)) { // if offset out of alowed range replace it by mean (*calparraw)[s][mo][mb][t].setOffset(meanhOffset); (*calparraw)[s][mo][mb][t].setOffsetMethod(0); (*calparraw)[s][mo][mb][t].setOffsetErr(100); offsets[s][mo][mb][t]=meanhOffset; hOffsetcorr->Fill(meanhOffset); } else // if offsets in allowed range and no error flag { hOffsetcorr->Fill(myoffset); (*calparraw)[s][mo][mb][t].setOffset(myoffset); (*calparraw)[s][mo][mb][t].setOffsetMethod(2); if(myerror>99) // if some nonsense value shows up in Err { (*calparraw)[s][mo][mb][t].setOffsetErr(100); offsetErr[s][mo][mb][t]=100; } else // if Err gives nomal values { (*calparraw)[s][mo][mb][t].setOffsetErr(myerror); } } } else { // if offsets contain error flags if(connected==-1) // if no wire is connected { (*calparraw)[s][mo][mb][t].setOffset(-7); offsets[s][mo][mb][t]=-7; hOffsetcorr->Fill(-7); } else // if wire is connected but error showed up { (*calparraw)[s][mo][mb][t].setOffset(myoffset); hOffsetcorr->Fill(myoffset); } (*calparraw)[s][mo][mb][t].setOffsetMethod(2); (*calparraw)[s][mo][mb][t].setOffsetErr(100); offsetErr[s][mo][mb][t]=100; } } Bool_t HMdcOffset::finalize(void) { // This function is called after the execute function is finished. At this point // the arrays for the drift-time are filled. Froms this arrays the histograms for // the drift-time and the integrated drift-time are filled. The fits for the calcutation // of the offsets are done and the offsets and the sigma of the offsets are // calculated .All histograms are written to a rootfile output and the information // of the fits to an ascii debugging output. The offset and the sigma of the offset // are filled into the container (HMdcCalParRaw) for the calibration parameters. // To characterize the method of calculation of the offsets the function setOffsetMethod() // of HMdcCalParRaw is used. As default value for the method 2 is used for automatic // calibration. If no calibration is done this value is set to 0. cout << "From HMdcOffset::finalize" << endl; // Start Stop Watch TStopwatch timer; timer.Start(); // open Root file for writing htime1temp = new MyHist("time1temp","time1temp", nbin,-nbin+0.5,0.5); //temp time1 hist. TFile *file = NULL; offsetTuple=NULL; offsetPulserTuple=NULL; ferrorlog=fopen("offset_error_log.txt","w"); // open file for log of errors/warnings if (fNameRootOffset) { file = new TFile(fNameRootOffset,"RECREATE"); file->cd(); offsetTuple=new TNtuple("offset","offset","s:m:mb:tdc:lay:cell:slope:slopeErr:off:offErr:integral:off1:fit1slope:fit2slope"); offsetPulserTuple=new TNtuple("multipeaks","multipeaks","s:m:mb:tdc:lay:cell:off:offErr:integral:p1:p2:p3:p4:p5"); // open ascii file for writing ofstream *fout=NULL; if (fNameAsciiOffset) { fout = openAsciiFile(); } TH1F *hOffset = new TH1F("Offset", "Offset", 512, 0, 2048); TH1F *hOffsetcorr = new TH1F("Offsetcorr", "Offsetcorr", 512, 0, 2048); Int_t err=-3; meanhOffset=0; initArrays(); HDetector *mdcDet = gHades->getSetup()->getDetector("Mdc"); if (!mdcDet) cout << "Error in HMdcOffset::finalize: Mdc-Detector setup (gHades->getSetup()->getDetector(\"Mdc\")) missing." << endl; else for(Int_t s=0; s<6; s++) { //loop over sectors cout<<"Sector "<getModule(s, mo)) continue; TDirectory *dirMod=NULL; if (dirSec) dirMod=Mkdir(dirSec, "module", mo); createHist_2D(s,mo); Int_t nMb=(*calparraw)[s][mo].getSize(); for(Int_t mb=0; mbmkdir("hinv"); dirMbo->mkdir("hint"); } Int_t nTdc=(*calparraw)[s][mo][mb].getSize(); for(Int_t t=0; tTDirectory::Cd(".."); cout << "." << flush; } writeHist_2D(); deleteHist_2D(); cout<<" "<TDirectory::Cd(".."); } cout<<" "<TDirectory::Cd(".."); } cout << endl; // write offsets to calparraw myoffset=0; myerror=0; meanhOffset=(Float_t)((Int_t)(hOffset->GetMean())); for(Int_t s=0; s<6; s++) { //loop over sectors for(Int_t mo=0; mo<4; mo++) { //loop over modules if (!mdcDet->getModule(s, mo)) continue; Int_t nMb=(*calparraw)[s][mo].getSize(); for(Int_t mb=0; mbWrite(); hOffsetcorr->Write(); offsetTuple->Write(); offsetPulserTuple->Write(); delete hOffset; delete hOffsetcorr; // close root file file->Save(); file->Close(); delete file; if (fNameAsciiOffset) { // close ascii file fout->close(); delete fout; } else { cout<<"WARNING: NO ASCII OUTPUT SET, NO FILE WRITTEN TO DISK!"<mkdir(sDir); dirOld->cd(sDir); // free (sDir); return dirNew; } Float_t HMdcOffset::getstarttime(){ // Need some work for multiple hists in start detector // Better select multiplicity 1 in start. Int_t i=0; Int_t startmod=-1; HStartHit* starthit=0; iter_start->Reset(); Float_t starttime=0; while ((starthit=(HStartHit *)iter_start->Next())!=0) { startmod=starthit->getModule(); if(startmod==0) { i++; if(starthit->getFlag()) starttime=starthit->getTime(); } } if (i!=1) Error("getstarttime(int)","Multiplicity in Start > 1 or 0"); return starttime; } Int_t HMdcOffset::execute() { Int_t result=0; if(useClusters)result=executeClus(); else result=executeRaw(); return result; } Int_t HMdcOffset::executeClus() { // Fired cells are take from the list of Cells inside one HMdcClus. // Raw data of Time1 multiplied by the slope of the channel taken from the // container of the calibration parameters are filled into the array for the // drift-time . This array contains 2048 (corresponding to the resulution of // the tdc chip) entries for each tdc channel. static HMdcRaw *raw =NULL; static HMdcClus *clus=NULL; Int_t s, mo, mb, t; Int_t l,c; Float_t testTime1=0; Float_t testTime2=0; Double_t xp1,yp1,zp1,xp2,yp2,zp2,signalpath; Double_t wireoff =0.; Float_t starttime=0; Float_t tof =0; iter_clus->Reset(); if(skipcounter>nSkipEvents) { if(!noStart) // Start Time is used { starttime=getstarttime(); } while ((clus=(HMdcClus*)iter_clus->Next())) { s=mo=mb=t==-99; l=c=-99; xp1=clus->getX(); yp1=clus->getY(); zp1=clus->getZ(); xp2=clus->getXTarg(); yp2=clus->getYTarg(); zp2=clus->getZTarg(); s =clus->getSec(); locraw[0]=s; Int_t ioseg=clus->getIOSeg(); Int_t mod=clus->getMod(); for(Int_t lay=0;lay<12;lay++) { // loop over layers //---------------finding module----------- if(mod<0) { // combined clusters if(ioseg==0){ (lay<6)? locraw[1]=0 : locraw[1]=1; }else if(ioseg==1){ (lay<6)? locraw[1]=2 : locraw[1]=3; } } else { // chamber clusters locraw[1]=mod; } mo=locraw[1]; //---------------finding layer------------ (lay<6)? l=lay : l=lay-6; //---------------------------------------- Int_t nCells=clus->getNCells(lay); for(Int_t cell=0;cellgetCell(lay,cell); if(useWireOffset) { signalpath=(*sizescells)[s][mo][l].getSignPath(xp1,yp1,zp1,xp2,yp2,zp2,c); if(signalpath>0) wireoff=signalpath*signalspeed; } HMdcLookupCell& mycell=(*lookupraw)[s][mo][l][c]; mb=mycell.getNMoth(); t =mycell.getNChan(); locraw[2]=mb; locraw[3]=t; raw=(HMdcRaw*)rawCat->getObject(locraw); if(((*calparraw)[s][mo][mb][t].getSlope())!=0) { testTime1=raw->getTime(1)-(starttime/(*calparraw)[s][mo][mb][t].getSlope()); testTime2=raw->getTime(2)-(starttime/(*calparraw)[s][mo][mb][t].getSlope()); } else { testTime1=raw->getTime(1); testTime2=raw->getTime(2); } if(useTof) tof=toffunc[mo][l]->Eval(c); // if useTof is switched on if(useTimeCuts) // if Time Cuts and Start Time { if(testTimeCuts(s,mo,testTime1,testTime2)) { // we have to use Float_ts here (*hreverse)[s][mo][mb][t] [ (Int_t)(2048-((Float_t)(raw->getTime(1))*(*calparraw)[s][mo][mb][t].getSlope())+starttime-wireoff-tof) ]++; } } else { // No Time Cuts and Start Time (*hreverse)[s][mo][mb][t] [ (Int_t)(2048-((Float_t)(raw->getTime(1))*(*calparraw)[s][mo][mb][t].getSlope())+starttime-wireoff-tof) ]++; } } } } if(eventcounter%nStep==0){ cout<Reset(); if(skipcounter>nSkipEvents) { if(!noStart) // Start Time is used { starttime=getstarttime(); } while ((raw=(HMdcRaw*)iter->Next())) { s=mo=mb=t=-99; raw->getAddress(s, mo, mb, t); if(((*calparraw)[s][mo][mb][t].getSlope())!=0) { testTime1=raw->getTime(1)-(starttime/(*calparraw)[s][mo][mb][t].getSlope()); testTime2=raw->getTime(2)-(starttime/(*calparraw)[s][mo][mb][t].getSlope()); } else { testTime1=raw->getTime(1); testTime2=raw->getTime(2); } if(useTof) { HMdcLookupChan& chan=(*lookupgeom)[s][mo][mb][t]; Int_t l= chan.getNLayer(); Int_t c= chan.getNCell(); tof=toffunc[mo][l]->Eval(c); } if(useTimeCuts) // if Time Cuts and Start Time { if(testTimeCuts(s,mo,testTime1,testTime2)) { // we have to use Float_ts here (*hreverse)[s][mo][mb][t] [ (Int_t)(2048-((Float_t)(raw->getTime(1))*(*calparraw)[s][mo][mb][t].getSlope())+starttime-tof) ]++; } } else { // No Time Cuts and Start Time (*hreverse)[s][mo][mb][t] [ (Int_t)(2048-((Float_t)(raw->getTime(1))*(*calparraw)[s][mo][mb][t].getSlope())+starttime-tof) ]++; } } if(eventcounter%nStep==0){ cout<