X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;ds=sidebyside;f=RALICE%2FAliSignal.cxx;h=8c2b4ee4d08b530f86ed0f49beb891e14952ee16;hb=1a7cb23298df61e8a0478585c891bf0061a77d3c;hp=6a4bd982d6fb8f7228a7b18203f447699a1c9259;hpb=965bd2377e4ae4a27527a810b44b77ea83f242b1;p=u%2Fmrichter%2FAliRoot.git diff --git a/RALICE/AliSignal.cxx b/RALICE/AliSignal.cxx index 6a4bd982d6f..8c2b4ee4d08 100644 --- a/RALICE/AliSignal.cxx +++ b/RALICE/AliSignal.cxx @@ -19,6 +19,19 @@ // Class AliSignal // Generic handling of (extrapolated) detector signals. // +// The user can decide to store either calibrated or uncalibrated signals. +// Via the specification of a gain and offset or/and an explicit +// (de)calibration function both calibrated and uncalibrated signals +// can always be obtained. For details see the documentation of the +// memberfunction GetSignal() and the class AliAttrib. +// The explicit specification of a (de)calibration function offers the +// maximum flexibility and also allows automatic indication whether +// calibrated or uncalibrated data has been stored. +// The latter can be achieved by only specifying a calibration function +// (and no de-calibration function) in case uncalibrated data is stored, +// whereas in case of stored calibrated data the user should only +// provide a de-calibration function (and no calibration function). +// // Note : // ------ // Signal positions (r) and reference frames (f) are specified via @@ -63,29 +76,34 @@ // signal=82.5; // e.g. signal time in ns // error=2.01; // offset=0.003; -// q.SetSlotName("TOF"); +// q.SetSlotName("TOF",1); // q.SetSignal(signal,1); // q.SetSignalError(error,1); // q.SetOffset(offset,1); // signal=268.1; // e.g. ADC value of signal // error=3.75; // gain=120.78; +// offset=1.5732; // // Addressing via name specification instead of index -// q.SetSlotName("ADC"); +// q.SetSlotName("ADC",2); // q.SetSignal(signal,"ADC"); // q.SetSignalError(error,"ADC"); // q.SetGain(gain,"ADC"); +// q.SetOffset(offset,"ADC"); // signal=23.7; // e.g. corresponding dE/dx value // error=0.48; -// offset=0.2; -// gain=150; -// q.SetSlotName("dE/dx"); -// q.SetSignal(signal,3); -// q.SetSignalError(error,3); -// q.SetOffset(offset,3); -// q.SetGain(gain,3); -// -// Float_t dedx=q.GetSignal("dE/dx"); +// TF1 f=("calib","[0]*pow(x,2)+[1]"); // dE/dx calib. function +// f.SetParameter(0,3.285); +// f.SetParameter(1,-18.67); +// q.SetSlotName("dE/dx",3); +// q.SetCalFunction(&f,"dE/dx"); +// q.SetSignal(signal,"dE/dx"); +// q.SetSignalError(error,"dE/dx"); +// +// // Signal retrieval with various (de)calibration modes +// Float_t tof=q.GetSignal("TOF"); +// Float_t adc=q.GetSignal("ADC",1); +// Float_t dedx=q.GetSignal("dE/dx",3); // //--- Author: Nick van Eijndhoven 23-jan-1999 UU-SAP Utrecht //- Modified: NvE $Date$ UU-SAP Utrecht @@ -105,9 +123,11 @@ AliSignal::AliSignal() : TNamed(),AliPosition(),AliAttrib() // when entering values and/or errors. fSignals=0; fDsignals=0; + fSigflags=0; fWaveforms=0; fLinks=0; fDevice=0; + fTracks=0; } /////////////////////////////////////////////////////////////////////////// AliSignal::~AliSignal() @@ -123,6 +143,11 @@ AliSignal::~AliSignal() delete fDsignals; fDsignals=0; } + if (fSigflags) + { + delete fSigflags; + fSigflags=0; + } if (fWaveforms) { delete fWaveforms; @@ -133,6 +158,17 @@ AliSignal::~AliSignal() delete fLinks; fLinks=0; } + if (fTracks) + { + // Remove this signal from all related tracks + for (Int_t i=1; i<=GetNtracks(); i++) + { + AliTrack* tx=GetTrack(i); + if (tx) tx->RemoveSignal(*this,0); + } + delete fTracks; + fTracks=0; + } } /////////////////////////////////////////////////////////////////////////// AliSignal::AliSignal(const AliSignal& s) : TNamed(s),AliPosition(s),AliAttrib(s) @@ -140,8 +176,10 @@ AliSignal::AliSignal(const AliSignal& s) : TNamed(s),AliPosition(s),AliAttrib(s) // Copy constructor fSignals=0; fDsignals=0; + fSigflags=0; fWaveforms=0; fLinks=0; + fTracks=0; // Don't copy the owning device pointer for the copy fDevice=0; @@ -150,15 +188,21 @@ AliSignal::AliSignal(const AliSignal& s) : TNamed(s),AliPosition(s),AliAttrib(s) Double_t val; for (Int_t i=1; i<=n; i++) { - val=s.GetSignal(i); - SetSignal(val,i); + if (s.GetSignalFlag(i)) + { + val=s.GetSignal(i); + SetSignal(val,i); + } } n=s.GetNerrors(); for (Int_t j=1; j<=n; j++) { - val=s.GetSignalError(j); - SetSignalError(val,j); + if (s.GetErrorFlag(j)) + { + val=s.GetSignalError(j); + SetSignalError(val,j); + } } n=s.GetNwaveforms(); @@ -180,6 +224,17 @@ AliSignal::AliSignal(const AliSignal& s) : TNamed(s),AliPosition(s),AliAttrib(s) TObject* obj=s.GetLink(slot,pos); if (obj) SetLink(obj,slot,pos); } + + Int_t ntk=s.GetNtracks(); + if (ntk) + { + fTracks=new TObjArray(ntk); + for (Int_t it=1; it<=ntk; it++) + { + AliTrack* tx=s.GetTrack(it); + fTracks->Add(tx); + } + } } /////////////////////////////////////////////////////////////////////////// void AliSignal::Reset(Int_t mode) @@ -195,6 +250,9 @@ void AliSignal::Reset(Int_t mode) // The default when invoking Reset() corresponds to mode=0. // // Note : In all cases the storage of the various links will be reset. +// The UniqueID, name and title will NOT be reset. +// In case the user wants to reset these attributes, this has to +// be done explicitly via the SET facilities. // // The usage of mode=0 allows to re-use the allocated memory for new // signal (and error) values. This behaviour is preferable (i.e. faster) @@ -229,6 +287,12 @@ void AliSignal::Reset(Int_t mode) if (fLinks) fLinks->Reset(); fDevice=0; + + if (fTracks) + { + delete fTracks; + fTracks=0; + } } /////////////////////////////////////////////////////////////////////////// void AliSignal::ResetSignals(Int_t mode) @@ -250,19 +314,26 @@ void AliSignal::ResetSignals(Int_t mode) mode=0; } + Int_t sflag=0; + Int_t eflag=0; + if (fSignals && (mode==0 || mode==1)) { - for (Int_t i=0; iGetSize(); i++) + for (Int_t i=1; i<=fSignals->GetSize(); i++) { - fSignals->AddAt(0,i); + fSignals->AddAt(0,i-1); + eflag=GetErrorFlag(i); + SetSigFlags(0,eflag,i); } } if (fDsignals && (mode==0 || mode==2)) { - for (Int_t j=0; jGetSize(); j++) + for (Int_t j=1; j<=fDsignals->GetSize(); j++) { - fDsignals->AddAt(0,j); + fDsignals->AddAt(0,j-1); + sflag=GetSignalFlag(j); + SetSigFlags(sflag,0,j); } } @@ -300,6 +371,31 @@ void AliSignal::DeleteSignals(Int_t mode) fDsignals=0; } + Int_t sflag=0; + Int_t eflag=0; + + if (mode==0) + { + delete fSigflags; + fSigflags=0; + } + else if (mode==1) + { + for (Int_t i=1; i<=fSigflags->GetSize(); i++) + { + eflag=GetErrorFlag(i); + SetSigFlags(0,eflag,i); + } + } + else if (mode==2) + { + for (Int_t j=1; j<=fSigflags->GetSize(); j++) + { + sflag=GetSignalFlag(j); + SetSigFlags(sflag,0,j); + } + } + DeleteWaveform(0); } /////////////////////////////////////////////////////////////////////////// @@ -325,6 +421,9 @@ void AliSignal::SetSignal(Double_t sig,Int_t j) } fSignals->AddAt(float(sig),j-1); + + Int_t eflag=GetErrorFlag(j); + SetSigFlags(1,eflag,j); } /////////////////////////////////////////////////////////////////////////// void AliSignal::SetSignal(Double_t sig,TString name) @@ -364,6 +463,9 @@ void AliSignal::AddSignal(Double_t sig,Int_t j) Float_t sum=(fSignals->At(j-1))+sig; fSignals->AddAt(sum,j-1); + + Int_t eflag=GetErrorFlag(j); + SetSigFlags(1,eflag,j); } /////////////////////////////////////////////////////////////////////////// void AliSignal::AddSignal(Double_t sig,TString name) @@ -384,46 +486,153 @@ Float_t AliSignal::GetSignal(Int_t j,Int_t mode) const { // Provide signal value of the j-th (default j=1) slot. // Note : The first signal slot is at j=1. -// In case no signal is present or the argument j is invalid, 0 is returned. -// The parameter "mode" allows for automatic gain etc... correction of the signal. +// In case no signal is present or the input argument "j" or "mode" is invalid, +// the value 0 is returned. +// The parameter "mode" allows for automatic (de)calibration of the signal +// (e.g. gain etc... correction or via explicit (de)calibration functions). // // mode = 0 : Just the j-th signal is returned. // 1 : The j-th signal is corrected for the gain, offset, dead flag etc... +// In case the j-th slot was marked dead, 0 is returned. // In case the gain value was not set, gain=1 will be assumed. // In case the gain value was 0, a signal value of 0 is returned. // In case the offset value was not set, offset=0 will be assumed. +// 2 : Same as mode=1 but gain, offset dead flag etc... are taken from +// the AliDevice which owns this AliSignal object. +// The corresponding AliDevice slot is obtained via matching of +// the slotnames. In case this fails, the slotindex "j" of the +// input argument will be used. +// In case this AliSignal object has no parent AliDevice, just +// the j-th signal is returned (like with mode=0). +// 3 : The j-th signal is corrected using the corresponding calibration +// function. // In case the j-th slot was marked dead, 0 is returned. +// In case no calibration function is present, just the j-th signal +// is returned (like with mode=0). +// 4 : Same as mode=3 but the calibration function and dead flag are +// taken from the AliDevice which owns this AliSignal object. +// The corresponding AliDevice slot is obtained via matching of +// the slotnames. In case this fails, the slotindex "j" of the +// input argument will be used. +// 5 : Same as mode=2 but in case no parent AliDevice is present +// an automatic switch to mode=1 will be made. +// 6 : Same as mode=4 but in case no parent AliDevice is present +// an automatic switch to mode=3 will be made. +// 7 : Same as mode=3 but in case no calibration function is present +// an automatic switch to mode=4 will be made. +// 8 : Same as mode=7 but also the corresponding dead flag of the +// parent device (if any) will be checked. +// If either the dead flag of the requested signal slot of this +// AliSignal object or the corresponding parent device slot is +// set, 0 is returned. +// +// <0 : The corresponding de-correction or de-calibration is performed // // The corrected signal (sigc) is determined as follows : // // sigc=(signal/gain)-offset // +// The de-corrected signal is determined as follows : +// +// signal=(sigc+offset)*gain +// // The default is mode=0. + if (abs(mode)>8) return 0; + + Int_t jcal=j; Float_t sig=0; Float_t gain=1; Float_t offset=0; + + // Get the corresponding slot index (and dead flag) of the parent device + Int_t pj=0; + Int_t pdead=0; + AliSignal* parent=(AliSignal*)GetDevice(); + if ((abs(mode)==2 || abs(mode)>=4) && parent) + { + TString name=GetSlotName(j); + if (strlen(name.Data())) pj=parent->GetSlotIndex(name); + if (abs(mode)==8 && pj) pdead=parent->GetDeadValue(pj); + } + if (mode==8) mode=7; + if (mode==-8) mode=-7; + + AliSignal* sx=(AliSignal*)this; + + TF1* f=0; + if (mode==7) + { + f=sx->GetCalFunction(jcal); + if (f) + { + mode=3; + } + else + { + mode=4; + } + } + if (mode==-7) + { + f=sx->GetDecalFunction(jcal); + if (f) + { + mode=-3; + } + else + { + mode=-4; + } + } + + if (abs(mode)==2 || abs(mode)>=4) + { + sx=(AliSignal*)GetDevice(); + if (pj) jcal=pj; + } + if (!sx && abs(mode)>=5) sx=(AliSignal*)this; + if (mode==5) mode=2; + if (mode==-5) mode=-2; + if (mode==6) mode=3; + if (mode==-6) mode=-3; + if (fSignals) { if (j>0 && j<=(fSignals->GetSize())) { sig=fSignals->At(j-1); - if (mode==0) return sig; + if (mode==0 || !sx) return sig; - // Correct the signal for the gain, offset, dead flag etc... - if (GetDeadValue(j)) return 0; + // Check for the dead flag setting + if (sx->GetDeadValue(jcal) || pdead) return 0; - if (GetGainFlag(j)) gain=GetGain(j); - if (GetOffsetFlag(j)) offset=GetOffset(j); - - if (fabs(gain)>0.) + // (De)correct the signal for the gain and offset + if (abs(mode)==1 || abs(mode)==2) { - sig=(sig/gain)-offset; + if (sx->GetGainFlag(jcal)) gain=sx->GetGain(jcal); + if (sx->GetOffsetFlag(jcal)) offset=sx->GetOffset(jcal); + + if (fabs(gain)>0.) + { + if (mode>0) sig=(sig/gain)-offset; // Gain and offset correction + if (mode<0) sig=(sig+offset)*gain; // Gain and offset de-correction + } + else + { + sig=0; + } + return sig; } - else + + // (De)calibrate the signal with the corresponding (de)calibration function + if (abs(mode)==3 || abs(mode)==4) { - sig=0; + f=sx->GetCalFunction(jcal); + if (mode<0) f=sx->GetDecalFunction(jcal); + if (f) sig=f->Eval(sig); + return sig; } } else @@ -438,18 +647,10 @@ Float_t AliSignal::GetSignal(TString name,Int_t mode) const { // Provide signal value of the name-specified slot. // In case no signal is present, 0 is returned. -// The parameter "mode" allows for automatic gain etc... correction of the signal. -// -// mode = 0 : Just the j-th signal is returned. -// 1 : The j-th signal is corrected for the gain, offset, dead flag etc... -// In case the gain value was not set, gain=1 will be assumed. -// In case the gain value was 0, a signal value of 0 is returned. -// In case the offset value was not set, offset=0 will be assumed. -// In case the j-th slot was marked dead, 0 is returned. -// -// The corrected signal (sigc) is determined as follows : -// -// sigc=(signal/gain)-offset +// The parameter "mode" allows for automatic (de)calibration of the signal +// (e.g. gain etc... correction or via explicit (de)calibration functions). +// For further details about the (de)calibration modes, please refer to the +// corresponding slot-index based memberfunction. // // The default is mode=0. // @@ -487,6 +688,9 @@ void AliSignal::SetSignalError(Double_t dsig,Int_t j) } fDsignals->AddAt(float(dsig),j-1); + + Int_t sflag=GetSignalFlag(j); + SetSigFlags(sflag,1,j); } /////////////////////////////////////////////////////////////////////////// void AliSignal::SetSignalError(Double_t dsig,TString name) @@ -539,29 +743,44 @@ Float_t AliSignal::GetSignalError(TString name) const return val; } /////////////////////////////////////////////////////////////////////////// -void AliSignal::Data(TString f) const +void AliSignal::Data(TString f,TString u) const { // Provide all signal information within the coordinate frame f. +// +// The string argument "u" allows to choose between different angular units +// in case e.g. a spherical frame is selected. +// u = "rad" : angles provided in radians +// "deg" : angles provided in degrees +// +// The defaults are f="car" and u="rad". const char* name=GetName(); const char* title=GetTitle(); - cout << " *" << ClassName() << "::Data*"; + cout << " *" << ClassName() << "::Data* Id : " << GetUniqueID(); if (strlen(name)) cout << " Name : " << name; if (strlen(title)) cout << " Title : " << title; cout << endl; cout << " Position"; - Ali3Vector::Data(f); + AliPosition::Data(f,u); if (fDevice) { const char* devname=fDevice->GetName(); const char* devtitle=fDevice->GetTitle(); - cout << " Owned by device : " << fDevice->ClassName(); + cout << " Owned by device : " << fDevice->ClassName() + << " Id : " << fDevice->GetUniqueID(); if (strlen(devname)) cout << " Name : " << devname; if (strlen(devtitle)) cout << " Title : " << devtitle; cout << endl; } + // Provide an overview of the stored waveforms + ListWaveform(-1); + + // Provide an overview of the associated tracks + ListTrack(-1); + + // Provide an overview of all the data and attribute slots List(-1); } /////////////////////////////////////////////////////////////////////////// @@ -584,22 +803,26 @@ void AliSignal::List(Int_t j) const const char* name=GetName(); const char* title=GetTitle(); - cout << " *" << ClassName() << "::Data*"; + cout << " *" << ClassName() << "::Data* Id :" << GetUniqueID(); if (strlen(name)) cout << " Name : " << name; if (strlen(title)) cout << " Title : " << title; cout << endl; + if (fDevice) + { + const char* devname=fDevice->GetName(); + const char* devtitle=fDevice->GetTitle(); + cout << " Owned by device : " << fDevice->ClassName(); + if (strlen(devname)) cout << " Name : " << devname; + if (strlen(devtitle)) cout << " Title : " << devtitle; + cout << endl; + } } - Int_t nvalues=GetNvalues(); - Int_t nerrors=GetNerrors(); - Int_t nwforms=GetNwaveforms(); + Int_t n=GetNslots(); Int_t nlinkslots=0; - if (fLinks) nlinkslots=fLinks->GetMaxColumn(); - Int_t n=nvalues; - if (nerrors>n) n=nerrors; - if (nwforms>n) n=nwforms; + if (GetNlinks()) nlinkslots=fLinks->GetMaxColumn(); if (nlinkslots>n) n=nlinkslots; - + TObject* obj=0; Int_t nrefs=0; TArrayI posarr; @@ -609,38 +832,33 @@ void AliSignal::List(Int_t j) const { for (Int_t i=1; i<=n; i++) { - cout << " Slot : " << i; - if (i<=nvalues) cout << " Signal value : " << GetSignal(i); - if (i<=nerrors) cout << " error : " << GetSignalError(i); - AliAttrib::List(i); - cout << endl; - obj=GetWaveform(i); - if (obj) - { - const char* wfname=obj->GetName(); - const char* wftitle=obj->GetTitle(); - cout << " Waveform : " << obj->ClassName(); - if (strlen(wfname)) cout << " Name : " << wfname; - if (strlen(wftitle)) cout << " Title : " << wftitle; - cout << endl; - } obj=0; nrefs=GetIndices(obj,i,posarr); - for (Int_t k=0; kClassName(); - if (obj->InheritsFrom("TNamed")) + pos=posarr.At(k); + obj=GetLink(i,pos); + if (obj) { - const char* lname=obj->GetName(); - const char* ltitle=obj->GetTitle(); - if (strlen(lname)) cout << " Name : " << lname; - if (strlen(ltitle)) cout << " Title : " << ltitle; + cout << " Link at position " << pos << " to : " << obj->ClassName(); + if (obj->InheritsFrom("TNamed")) + { + const char* lname=obj->GetName(); + const char* ltitle=obj->GetTitle(); + if (strlen(lname)) cout << " Name : " << lname; + if (strlen(ltitle)) cout << " Title : " << ltitle; + } + cout << endl; } - cout << endl; } } } @@ -649,38 +867,33 @@ void AliSignal::List(Int_t j) const { if (j<=n) { - cout << " Slot : " << j; - if (j<=nvalues) cout << " Signal value : " << GetSignal(j); - if (j<=nerrors) cout << " error : " << GetSignalError(j); - AliAttrib::List(j); - cout << endl; - obj=GetWaveform(j); - if (obj) - { - const char* wfnamej=obj->GetName(); - const char* wftitlej=obj->GetTitle(); - cout << " Waveform : " << obj->ClassName(); - if (strlen(wfnamej)) cout << " Name : " << wfnamej; - if (strlen(wftitlej)) cout << " Title : " << wftitlej; - cout << endl; - } obj=0; nrefs=GetIndices(obj,j,posarr); - for (Int_t kj=0; kjClassName(); - if (obj->InheritsFrom("TNamed")) + pos=posarr.At(kj); + obj=GetLink(j,pos); + if (obj) { - const char* lnamej=obj->GetName(); - const char* ltitlej=obj->GetTitle(); - if (strlen(lnamej)) cout << " Name : " << lnamej; - if (strlen(ltitlej)) cout << " Title : " << ltitlej; + cout << " Link at position " << pos << " to : " << obj->ClassName(); + if (obj->InheritsFrom("TNamed")) + { + const char* lnamej=obj->GetName(); + const char* ltitlej=obj->GetTitle(); + if (strlen(lnamej)) cout << " Name : " << lnamej; + if (strlen(ltitlej)) cout << " Title : " << ltitlej; + } + cout << endl; } - cout << endl; } } } @@ -701,41 +914,291 @@ void AliSignal::List(TString name) const if (j>0) List(j); } /////////////////////////////////////////////////////////////////////////// +void AliSignal::ListWaveform(Int_t j) const +{ +// Provide information for the j-th waveform. +// The first waveform is at j=1. +// In case j=0 (default) the info of all waveforms will be listed. +// In case j=-1 the info of all waveforms will be listed, but the header +// information will be suppressed. + + if (j<-1) + { + cout << " *AliSignal::ListWaveform* Invalid argument j = " << j << endl; + return; + } + + if (j != -1) + { + const char* name=GetName(); + const char* title=GetTitle(); + + cout << " *" << ClassName() << "::Data* Id :" << GetUniqueID(); + if (strlen(name)) cout << " Name : " << name; + if (strlen(title)) cout << " Title : " << title; + cout << endl; + if (fDevice) + { + const char* devname=fDevice->GetName(); + const char* devtitle=fDevice->GetTitle(); + cout << " Owned by device : " << fDevice->ClassName(); + if (strlen(devname)) cout << " Name : " << devname; + if (strlen(devtitle)) cout << " Title : " << devtitle; + cout << endl; + } + } + + Int_t n=GetNwaveforms(); + TObject* obj=0; + + if (j<=0) + { + for (Int_t i=1; i<=n; i++) + { + obj=GetWaveform(i); + if (obj) + { + const char* wfname=obj->GetName(); + const char* wftitle=obj->GetTitle(); + cout << " Waveform " << i << " : " << obj->ClassName(); + if (strlen(wfname)) cout << " Name : " << wfname; + if (strlen(wftitle)) cout << " Title : " << wftitle; + cout << endl; + } + } + } + else + { + if (j<=n) + { + obj=GetWaveform(j); + if (obj) + { + const char* wfnamej=obj->GetName(); + const char* wftitlej=obj->GetTitle(); + cout << " Waveform " << j << " : " << obj->ClassName(); + if (strlen(wfnamej)) cout << " Name : " << wfnamej; + if (strlen(wftitlej)) cout << " Title : " << wftitlej; + cout << endl; + } + } + } +} +/////////////////////////////////////////////////////////////////////////// +void AliSignal::ListTrack(Int_t j) const +{ +// Provide information for the j-th associated track. +// The first associated track is at j=1. +// In case j=0 (default) the info of all associated tracks will be listed. +// In case j=-1 the info of all tracks will be listed, but the header +// information will be suppressed. + + if (j<-1) + { + cout << " *AliSignal::ListTrack* Invalid argument j = " << j << endl; + return; + } + + if (j != -1) + { + const char* name=GetName(); + const char* title=GetTitle(); + + cout << " *" << ClassName() << "::Data* Id :" << GetUniqueID(); + if (strlen(name)) cout << " Name : " << name; + if (strlen(title)) cout << " Title : " << title; + cout << endl; + if (fDevice) + { + const char* devname=fDevice->GetName(); + const char* devtitle=fDevice->GetTitle(); + cout << " Owned by device : " << fDevice->ClassName(); + if (strlen(devname)) cout << " Name : " << devname; + if (strlen(devtitle)) cout << " Title : " << devtitle; + cout << endl; + } + } + + Int_t n=GetNtracks(); + AliTrack* tx=0; + + if (j<=0) + { + for (Int_t i=1; i<=n; i++) + { + tx=GetTrack(i); + if (tx) + { + const char* txname=tx->GetName(); + const char* txtitle=tx->GetTitle(); + cout << " Track " << i << " : " << tx->ClassName() << " Id : " << tx->GetId(); + if (strlen(txname)) cout << " Name : " << txname; + if (strlen(txtitle)) cout << " Title : " << txtitle; + cout << endl; + } + } + } + else + { + if (j<=n) + { + tx=GetTrack(j); + if (tx) + { + const char* txnamej=tx->GetName(); + const char* txtitlej=tx->GetTitle(); + cout << " Track " << j << " : " << tx->ClassName() << " Id : " << tx->GetId(); + if (strlen(txnamej)) cout << " Name : " << txnamej; + if (strlen(txtitlej)) cout << " Title : " << txtitlej; + cout << endl; + } + } + } +} +/////////////////////////////////////////////////////////////////////////// Int_t AliSignal::GetNvalues() const { // Provide the number of values for this signal. + + if (!fSignals) return 0; + Int_t n=0; - if (fSignals) n=fSignals->GetSize(); + for (Int_t i=1; i<=fSigflags->GetSize(); i++) + { + if (GetSignalFlag(i)) n=i; + } + return n; } /////////////////////////////////////////////////////////////////////////// Int_t AliSignal::GetNerrors() const { // Provide the number specified errors on the values for this signal. + + if (!fDsignals) return 0; + Int_t n=0; - if (fDsignals) n=fDsignals->GetSize(); + for (Int_t i=1; i<=fSigflags->GetSize(); i++) + { + if (GetErrorFlag(i)) n=i; + } + return n; } /////////////////////////////////////////////////////////////////////////// -Int_t AliSignal::GetNwaveforms() const +void AliSignal::SetSigFlags(Int_t is,Int_t ie,Int_t j) { -// Provide the number specified waveforms for this signal. - Int_t n=0; - if (fWaveforms) n=fWaveforms->GetSize(); - return n; +// Store signal and/or error value flags of the j-th (default j=1) slot. +// Note : The first slot is at j=1. +// In case the value of the index j exceeds the maximum number of reserved +// slots for the flags, the number of reserved slots for the flags is +// increased automatically. +// The value stored is : 10*signalflag + errorflag. + + if (j<1) + { + cout << " *AliSignal::SetSigFlags* Invalid argument j = " << j << endl; + return; + } + + if (!fSigflags) + { + fSigflags=new TArrayI(j); + } + + Int_t size=fSigflags->GetSize(); + + if (j>size) + { + fSigflags->Set(j); + } + + Int_t word=10*is+ie; + + fSigflags->AddAt(word,j-1); } /////////////////////////////////////////////////////////////////////////// -TH1F* AliSignal::GetWaveform(Int_t j) const +Int_t AliSignal::GetSignalFlag(Int_t j) const { -// Provide pointer to the waveform histogram of the j-th slot. - TH1F* waveform=0; - if (j <= GetNwaveforms()) waveform=(TH1F*)fWaveforms->At(j-1); - return waveform; +// Provide signal value flag of the j-th (default j=1) slot. +// +// flag = 1 : Signal value was set +// 0 : Signal value was not set +// +// Note : The first attribute slot is at j=1. +// In case j is invalid, 0 is returned. + + if (j<1) + { + cout << " *AliSignal::GetSignalFlag* Invalid argument j = " << j << endl; + return 0; + } + Int_t flag=0; + if (fSigflags) + { + if (j>0 && j<=(fSigflags->GetSize())) + { + Int_t word=fSigflags->At(j-1); + flag=word/10; + } + } + return flag; } /////////////////////////////////////////////////////////////////////////// -TH1F* AliSignal::GetWaveform(TString name) const +Int_t AliSignal::GetSignalFlag(TString name) const { -// Provide pointer to the waveform histogram of the name-specified slot. +// Provide signal value flag of the name-specified slot. +// +// flag = 1 : Signal value was set +// 0 : Signal value was not set +// +// +// This procedure involves a slot-index search based on the specified name +// at each invokation. This may become slow in case many slots have been +// defined and/or when this procedure is invoked many times. +// In such cases it is preferable to use indexed addressing in the user code +// either directly or via a few invokations of GetSlotIndex(). + + Int_t j=GetSlotIndex(name); + Int_t flag=0; + if (j>0) flag=GetSignalFlag(j); + return flag; +} +/////////////////////////////////////////////////////////////////////////// +Int_t AliSignal::GetErrorFlag(Int_t j) const +{ +// Provide error value flag of the j-th (default j=1) slot. +// +// flag = 1 : Error value was set +// 0 : Error value was not set +// +// Note : The first attribute slot is at j=1. +// In case j is invalid, 0 is returned. + + if (j<1) + { + cout << " *AliSignal::GetErrorFlag* Invalid argument j = " << j << endl; + return 0; + } + Int_t flag=0; + if (fSigflags) + { + if (j>0 && j<=(fSigflags->GetSize())) + { + Int_t word=fSigflags->At(j-1); + flag=word%10; + } + } + return flag; +} +/////////////////////////////////////////////////////////////////////////// +Int_t AliSignal::GetErrorFlag(TString name) const +{ +// Provide error value flag of the name-specified slot. +// +// flag = 1 : Error value was set +// 0 : Error value was not set +// // // This procedure involves a slot-index search based on the specified name // at each invokation. This may become slow in case many slots have been @@ -744,21 +1207,103 @@ TH1F* AliSignal::GetWaveform(TString name) const // either directly or via a few invokations of GetSlotIndex(). Int_t j=GetSlotIndex(name); + Int_t flag=0; + if (j>0) flag=GetErrorFlag(j); + return flag; +} +/////////////////////////////////////////////////////////////////////////// +Int_t AliSignal::GetNslots() const +{ +// Provide the number of existing slots. + + Int_t n=AliAttrib::GetNslots(); + + if (!fSigflags) return n; + + Int_t nflags=0; + for (Int_t i=0; iGetSize(); i++) + { + if (fSigflags->At(i)) nflags=i+1; + } + + if (nGetLast(); + return (n+1); +} +/////////////////////////////////////////////////////////////////////////// +TH1F* AliSignal::GetWaveform(Int_t j) const +{ +// Provide pointer to the j-th waveform histogram. TH1F* waveform=0; - if (j>0) waveform=GetWaveform(j); + if (j <= GetNwaveforms()) waveform=(TH1F*)fWaveforms->At(j-1); return waveform; } /////////////////////////////////////////////////////////////////////////// +TH1F* AliSignal::GetWaveform(TString name) const +{ +// Provide pointer to the waveform histogram with the specified name. +// In case no match is found, zero is returned. + Int_t n=GetNwaveforms(); + TString str; + for (Int_t i=1; i<=n; i++) + { + TH1F* waveform=GetWaveform(i); + if (waveform) + { + str=waveform->GetName(); + if (str == name) return waveform; + } + } + return 0; // No match found +} +/////////////////////////////////////////////////////////////////////////// +Int_t AliSignal::GetWaveformIndex(TString name) const +{ +// Provide index to the waveform histogram with the specified name. +// In case no match is found, zero is returned. + Int_t n=GetNwaveforms(); + TString str; + for (Int_t i=1; i<=n; i++) + { + TH1F* waveform=GetWaveform(i); + if (waveform) + { + str=waveform->GetName(); + if (str == name) return i; + } + } + return 0; // No match found +} +/////////////////////////////////////////////////////////////////////////// void AliSignal::SetWaveform(TH1F* waveform,Int_t j) { -// Set the 1D waveform histogram for the j-th slot. +// Set the 1D waveform histogram for the j-th waveform. // // Notes : -// The waveform of the first signal value is at j=1. +// The first waveform position at j=1. // j=1 is the default value. // // In case the value of the index j exceeds the maximum number of reserved -// slots for the waveforms, the number of reserved slots for the waveforms +// positions for the waveforms, the number of reserved positions for the waveforms // is increased automatically. // // In case the histo pointer argument has the same value as the current waveform @@ -772,6 +1317,8 @@ void AliSignal::SetWaveform(TH1F* waveform,Int_t j) // copy of the input histogram is created which becomes the current waveform // histogram. + if (j<1) return; + if (!fWaveforms) { fWaveforms=new TObjArray(j); @@ -797,26 +1344,12 @@ void AliSignal::SetWaveform(TH1F* waveform,Int_t j) } } /////////////////////////////////////////////////////////////////////////// -void AliSignal::SetWaveform(TH1F* waveform,TString name) -{ -// Set the 1D waveform histogram corresponding for the name-specified slot. -// -// This procedure involves a slot-index search based on the specified name -// at each invokation. This may become slow in case many slots have been -// defined and/or when this procedure is invoked many times. -// In such cases it is preferable to use indexed addressing in the user code -// either directly or via a few invokations of GetSlotIndex(). - - Int_t j=GetSlotIndex(name); - if (j>0) SetWaveform(waveform,j); -} -/////////////////////////////////////////////////////////////////////////// void AliSignal::ResetWaveform(Int_t j) { -// Reset the waveform of the j-th (default j=1) slot. +// Reset the histogram of the j-th (default j=1) waveform. // This memberfunction invokes TH1F::Reset() for the corresponding waveform(s). // To actually delete the histograms from memory, use DeleteWaveform(). -// Notes : The first signal value is at j=1. +// Notes : The first position is at j=1. // j=0 ==> All waveforms will be reset. if (!fWaveforms) return; @@ -848,22 +1381,15 @@ void AliSignal::ResetWaveform(Int_t j) /////////////////////////////////////////////////////////////////////////// void AliSignal::ResetWaveform(TString name) { -// Reset the waveform of the name-specified slot. -// -// This procedure involves a slot-index search based on the specified name -// at each invokation. This may become slow in case many slots have been -// defined and/or when this procedure is invoked many times. -// In such cases it is preferable to use indexed addressing in the user code -// either directly or via a few invokations of GetSlotIndex(). - - Int_t j=GetSlotIndex(name); +// Reset the waveform with the specified name. + Int_t j=GetWaveformIndex(name); if (j>0) ResetWaveform(j); } /////////////////////////////////////////////////////////////////////////// void AliSignal::DeleteWaveform(Int_t j) { -// Delete the waveform of the j-th (default j=1) slot. -// Notes : The first signal value is at j=1. +// Delete the histogram of the j-th (default j=1) waveform. +// Notes : The first position is at j=1. // j=0 ==> All waveforms will be deleted. if (!fWaveforms) return; @@ -896,15 +1422,8 @@ void AliSignal::DeleteWaveform(Int_t j) /////////////////////////////////////////////////////////////////////////// void AliSignal::DeleteWaveform(TString name) { -// Delete the waveform of the name-specified slot. -// -// This procedure involves a slot-index search based on the specified name -// at each invokation. This may become slow in case many slots have been -// defined and/or when this procedure is invoked many times. -// In such cases it is preferable to use indexed addressing in the user code -// either directly or via a few invokations of GetSlotIndex(). - - Int_t j=GetSlotIndex(name); +// Delete the waveform with the specified name. + Int_t j=GetWaveformIndex(name); if (j>0) DeleteWaveform(j); } /////////////////////////////////////////////////////////////////////////// @@ -921,10 +1440,12 @@ Int_t AliSignal::GetNlinks(TObject* obj,Int_t j) const return 0; } + if (!fLinks) return 0; + Int_t n=0; if (!j) { - if (fLinks) n=fLinks->GetNrefs(obj); + n=fLinks->GetNrefs(obj); } else { @@ -1001,6 +1522,14 @@ void AliSignal::SetLink(TObject* obj,Int_t j,Int_t k) // Therefore, in case the input argument "obj" points to an AliTrack (or derived) // object, the current signal is automatically related to this AliTrack // (or derived) object. +// Also a global link to this AliTrack (or derived) object will be stored +// via the AddTrack() facility. +// +// IMPORTANT NOTE : +// ---------------- +// In case one just wants to relate the current AliSignal to a certain AliTrack +// without a specific signal slot association, it is much more efficient +// (both memory and CPU wise) to use the memberfunction AddTrack() instead. // // Please also have a look at the docs of the memberfunction ResetLink() // to prevent the situation of stored pointers to non-existent object. @@ -1016,7 +1545,7 @@ void AliSignal::SetLink(TObject* obj,Int_t j,Int_t k) if (obj->InheritsFrom("AliTrack")) { AliTrack* t=(AliTrack*)obj; - t->AddSignal(*this); + AddTrack(*t,1); } } } @@ -1033,6 +1562,29 @@ void AliSignal::SetLink(TObject* obj,TString name,Int_t k) // defined and/or when this procedure is invoked many times. // In such cases it is preferable to use indexed addressing in the user code // either directly or via a few invokations of GetSlotIndex(). +// +// In case the pointer argument is zero, indeed a value of zero will be +// stored at the specified position (k) for the specified slotname. +// +// In principle any object derived from TObject can be referred to by this +// mechanism. +// However, this "linking back" facility was introduced to enable AliSignal slots +// to refer directly to the various AliTracks to which the AliSignal object itself +// is related (see AliTrack::AddSignal). +// Therefore, in case the input argument "obj" points to an AliTrack (or derived) +// object, the current signal is automatically related to this AliTrack +// (or derived) object. +// Also a global link to this AliTrack (or derived) object will be stored +// via the AddTrack() facility. +// +// IMPORTANT NOTE : +// ---------------- +// In case one just wants to relate the current AliSignal to a certain AliTrack +// without a specific signal slot association, it is much more efficient +// (both memory and CPU wise) to use the memberfunction AddTrack() instead. +// +// Please also have a look at the docs of the memberfunction ResetLink() +// to prevent the situation of stored pointers to non-existent object. Int_t j=GetSlotIndex(name); if (j>0) SetLink(obj,j,k); @@ -1062,6 +1614,14 @@ void AliSignal::AddLink(TObject* obj,Int_t j) // Therefore, in case the input argument "obj" points to an AliTrack (or derived) // object, the current signal is automatically related to this AliTrack // (or derived) object. +// Also a global link to this AliTrack (or derived) object will be stored +// via the AddTrack() facility. +// +// IMPORTANT NOTE : +// ---------------- +// In case one just wants to relate the current AliSignal to a certain AliTrack +// without a specific signal slot association, it is much more efficient +// (both memory and CPU wise) to use the memberfunction AddTrack() instead. // // Please also have a look at the docs of the memberfunction ResetLink() // to prevent the situation of stored pointers to non-existent object. @@ -1096,6 +1656,29 @@ void AliSignal::AddLink(TObject* obj,TString name) // defined and/or when this procedure is invoked many times. // In such cases it is preferable to use indexed addressing in the user code // either directly or via a few invokations of GetSlotIndex(). +// +// In case the pointer argument is zero, indeed a value of zero will be +// stored at the first free position of the specified slotname. +// +// In principle any object derived from TObject can be referred to by this +// mechanism. +// However, this "linking back" facility was introduced to enable AliSignal slots +// to refer directly to the various AliTracks to which the AliSignal object itself +// is related (see AliTrack::AddSignal). +// Therefore, in case the input argument "obj" points to an AliTrack (or derived) +// object, the current signal is automatically related to this AliTrack +// (or derived) object. +// Also a global link to this AliTrack (or derived) object will be stored +// via the AddTrack() facility. +// +// IMPORTANT NOTE : +// ---------------- +// In case one just wants to relate the current AliSignal to a certain AliTrack +// without a specific signal slot association, it is much more efficient +// (both memory and CPU wise) to use the memberfunction AddTrack() instead. +// +// Please also have a look at the docs of the memberfunction ResetLink() +// to prevent the situation of stored pointers to non-existent object. Int_t j=GetSlotIndex(name); if (j>0) AddLink(obj,j); @@ -1147,7 +1730,14 @@ void AliSignal::ResetLink(TString name,Int_t k) /////////////////////////////////////////////////////////////////////////// void AliSignal::ResetLinks(TObject* obj,Int_t j,Int_t k) { -// Reset single or multiple link(s) according to user specified selections. +// Reset single or multiple slot link(s) according to user specified selections. +// +// IMPORTANT NOTE : +// ---------------- +// This facility only acts on the slot related links. +// The global track reference list will not be affected. +// To remove all references to AliTrack (or derived) objects, please +// use the RemoveTrack() of RemoveTracks() memberfunctions. // // A link is only reset if the stored reference matches the argument "obj". // In case obj=0 no check on the matching of the stored reference is performed @@ -1203,7 +1793,14 @@ void AliSignal::ResetLinks(TObject* obj,Int_t j,Int_t k) /////////////////////////////////////////////////////////////////////////// void AliSignal::ResetLinks(TObject* obj,TString name,Int_t k) { -// Reset single or multiple link(s) according to user specified selections. +// Reset single or multiple slot link(s) according to user specified selections. +// +// IMPORTANT NOTE : +// ---------------- +// This facility only acts on the slot related links. +// The global track reference list will not be affected. +// To remove all references to AliTrack (or derived) objects, please +// use the RemoveTrack() of RemoveTracks() memberfunctions. // // A link is only reset if the stored reference matches the argument "obj". // In case obj=0 no check on the matching of the stored reference is performed @@ -1219,6 +1816,18 @@ void AliSignal::ResetLinks(TObject* obj,TString name,Int_t k) // defined and/or when this procedure is invoked many times. // In such cases it is preferable to use indexed addressing in the user code // either directly or via a few invokations of GetSlotIndex(). +// +// In general the user should take care of properly clearing the corresponding +// pointer here when the referred object is deleted. +// However, this "linking back" facility was introduced to enable AliSignal slots +// to refer directly to the various AliTracks to which the AliSignal object itself +// is related (see AliTrack::AddSignal). +// As such, the AliTrack destructor already takes care of clearing the corresponding +// links from the various AliSignal slots for all the AliSignal objects that were +// related to that AliTrack. +// So, in case the link introduced via SetLink() is the pointer of an AliTrack object, +// the user doesn't have to worry about clearing the corresponding AliTrack link from +// the AliSignal object when the corresponding AliTrack object is deleted. Int_t j=GetSlotIndex(name); if (j>0) ResetLinks(obj,j,k); @@ -1393,6 +2002,149 @@ AliDevice* AliSignal::GetDevice() const return (AliDevice*)fDevice; } /////////////////////////////////////////////////////////////////////////// +void AliSignal::AddTrack(AliTrack& t,Int_t mode) +{ +// Relate an AliTrack object to this signal. +// Only the pointer values are stored for (backward) reference, meaning +// that the tracks of which the pointers are stored are NOT owned +// by the AliSignal object. +// +// mode = 0 : Only the reference to the specified track is stored in +// the current signal, without storing the (backward) reference +// to this signal into the AliTrack structure. +// 1 : The (backward) reference to the current signal is also automatically +// stored into the AliTrack (or derived) object specified in the +// input argument. +// +// The default is mode=1. + + if (!fTracks) fTracks=new TObjArray(1); + + // Check if this track is already stored for this signal + Int_t ntk=GetNtracks(); + for (Int_t i=0; iAt(i)) return; + } + + fTracks->Add(&t); + if (mode==1) t.AddSignal(*this,0); +} +/////////////////////////////////////////////////////////////////////////// +void AliSignal::RemoveTrack(AliTrack& t,Int_t mode) +{ +// Remove related AliTrack object from this signal. +// Also all references (if any) to this track in the slot links area +// are removed. +// +// mode = 0 : All references to the specified track are removed from +// the current signal, without removing the (backward) reference +// to this signal from the AliTrack structure. +// 1 : The (backward) reference to the current signal is also automatically +// removed from the AliTrack (or derived) object specified in the +// input argument. +// +// The default is mode=1. + + if (fTracks) + { + AliTrack* test=(AliTrack*)fTracks->Remove(&t); + if (test) fTracks->Compress(); + } + + ResetLinks(&t); + + if (mode==1) t.RemoveSignal(*this,0); +} +/////////////////////////////////////////////////////////////////////////// +void AliSignal::RemoveTracks(Int_t mode) +{ +// Remove all related AliTrack objects from this signal. +// Also all references (if any) to the related tracks in the slot links area +// are removed. +// +// mode = 0 : All track references are removed from the current signal, +// without removing the (backward) references to this signal from +// the corresponding AliTrack objects. +// 1 : The (backward) references to the current signal are also automatically +// removed from the corresponding AliTrack (or derived) objects. +// +// The default is mode=1. + + if (!fTracks) return; + + Int_t ntk=GetNtracks(); + for (Int_t i=0; iAt(i); + if (tx) + { + ResetLinks(tx); + if (mode==1) tx->RemoveSignal(*this,0); + } + } + + delete fTracks; + fTracks=0; +} +/////////////////////////////////////////////////////////////////////////// +Int_t AliSignal::GetNtracks(AliTrack* t) const +{ +// Provide the number of related AliTracks. +// In case an AliTrack pointer is specified as input argument, +// the number returned will be the number of occurrences (i.e. 0 or 1) +// for that specified track. +// By default t=0, which implies that just the number of all associated +// tracks will be returned. + + if (!fTracks) return 0; + + Int_t ntk=fTracks->GetEntries(); + + if (!t) return ntk; + + for (Int_t i=0; iAt(i); + if (tx==t) return 1; + } + + return 0; +} +/////////////////////////////////////////////////////////////////////////// +AliTrack* AliSignal::GetTrack(Int_t j) const +{ +// Provide the related AliTrack number j. +// Note : j=1 denotes the first track. + + if (!fTracks) return 0; + + if ((j >= 1) && (j <= GetNtracks())) + { + return (AliTrack*)fTracks->At(j-1); + } + else + { + cout << " *AliSignal* track number : " << j << " out of range." + << " Ntk = " << GetNtracks() << endl; + return 0; + } +} +/////////////////////////////////////////////////////////////////////////// +AliTrack* AliSignal::GetIdTrack(Int_t id) const +{ +// Return the track with user identifier "id" of this signal + if (!fTracks) return 0; + + AliTrack* tx=0; + for (Int_t i=0; iAt(i); + if (id == tx->GetId()) return tx; + } + return 0; // No matching id found +} +/////////////////////////////////////////////////////////////////////////// TObject* AliSignal::Clone(const char* name) const { // Make a deep copy of the current object and provide the pointer to the copy.