X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=RALICE%2FAliSignal.cxx;h=c6bdd25139ce54abc4f520f2ea05ba394a05596f;hb=7d297381c12cca29a9615cd416f7b7291ab32450;hp=99afcf777e567c0d99a5e04d9e6f6f12331c729c;hpb=216d1d911d5f43db34b51f991cbb06bfe12ecbe6;p=u%2Fmrichter%2FAliRoot.git diff --git a/RALICE/AliSignal.cxx b/RALICE/AliSignal.cxx index 99afcf777e5..c6bdd25139c 100644 --- a/RALICE/AliSignal.cxx +++ b/RALICE/AliSignal.cxx @@ -109,6 +109,7 @@ //- Modified: NvE $Date$ UU-SAP Utrecht /////////////////////////////////////////////////////////////////////////// +#include #include "AliSignal.h" #include "AliTrack.h" #include "Riostream.h" @@ -123,9 +124,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() @@ -141,26 +144,31 @@ AliSignal::~AliSignal() delete fDsignals; fDsignals=0; } + if (fSigflags) + { + delete fSigflags; + fSigflags=0; + } if (fWaveforms) { delete fWaveforms; fWaveforms=0; } if (fLinks) + { + delete fLinks; + fLinks=0; + } + if (fTracks) { // Remove this signal from all related tracks - for (Int_t i=1; i<=fLinks->GetNobjects(); i++) + for (Int_t i=1; i<=GetNtracks(); i++) { - TObject* obj=fLinks->GetObject(i); - if (!obj) continue; - if (obj->InheritsFrom("AliTrack")) - { - AliTrack* tx=(AliTrack*)obj; - tx->RemoveSignal(*this); - } + AliTrack* tx=GetTrack(i); + if (tx) tx->RemoveSignal(*this,0); } - delete fLinks; - fLinks=0; + delete fTracks; + fTracks=0; } } /////////////////////////////////////////////////////////////////////////// @@ -169,25 +177,40 @@ 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; Int_t n=s.GetNvalues(); Double_t val; + Int_t lock; for (Int_t i=1; i<=n; i++) { - val=s.GetSignal(i); - SetSignal(val,i); + if (s.GetSignalFlag(i)) + { + val=s.GetSignal(i); + lock=s.GetLockValue(); + if (lock) Unlock(); + SetSignal(val,i); + if (lock) Lock(); + } } 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); + lock=s.GetLockValue(); + if (lock) Unlock(); + SetSignalError(val,j); + if (lock) Lock(); + } } n=s.GetNwaveforms(); @@ -209,6 +232,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) @@ -261,92 +295,138 @@ void AliSignal::Reset(Int_t mode) if (fLinks) fLinks->Reset(); fDevice=0; + + if (fTracks) + { + delete fTracks; + fTracks=0; + } } /////////////////////////////////////////////////////////////////////////// void AliSignal::ResetSignals(Int_t mode) { // Reset various signal data according to user selection. // -// mode = 0 Reset all signal values and their errors to 0. -// 1 Reset only signal values -// 2 Reset only signal errors +// mode = 0 Reset all signal values, their errors and all waveform histos. +// 1 Reset only signal values and waveform histos. +// 2 Reset only signal errors and waveform histos. +// -1 Reset only signal values. +// -2 Reset only signal errors. // // The default when invoking ResetSignals() corresponds to mode=0. -// -// Irrespective of the mode, the waveform histograms are reset. - if (mode<0 || mode>2) + if (abs(mode)>2) { cout << " *AliSignal::ResetSignals* Invalid argument mode = " << mode << endl; cout << " Default mode=0 will be used." << endl; mode=0; } - if (fSignals && (mode==0 || mode==1)) + Int_t sflag=0; + Int_t eflag=0; + + if (fSignals && (abs(mode)==0 || abs(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)) + if (fDsignals && (abs(mode)==0 || abs(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); } } - ResetWaveform(0); + if (mode>=0) ResetWaveform(0); } /////////////////////////////////////////////////////////////////////////// void AliSignal::DeleteSignals(Int_t mode) { // Delete storage arrays of various signal data according to user selection. // -// mode = 0 Delete arrays of both signal values and their errors. -// 1 Delete only signal values array -// 2 Delete only signal errors array +// mode = 0 Delete arrays of signal values, their errors and all waveform histos. +// 1 Delete only signal values array and waveform histos. +// 2 Delete only signal errors array and waveform histos. +// -1 Delete only signal values array. +// -2 Delete only signal errors array. // // The default when invoking DeleteSignals() corresponds to mode=0. -// -// Irrespective of the mode, the waveform histograms are deleted. - if (mode<0 || mode>2) + if (abs(mode)>2) { cout << " *AliSignal::DeleteSignals* Invalid argument mode = " << mode << endl; cout << " Default mode=0 will be used." << endl; mode=0; } - if (fSignals && (mode==0 || mode==1)) + if (fSignals && (abs(mode)==0 || abs(mode)==1)) { delete fSignals; fSignals=0; } - if (fDsignals && (mode==0 || mode==2)) + if (fDsignals && (abs(mode)==0 || abs(mode)==2)) { delete fDsignals; fDsignals=0; } - DeleteWaveform(0); + Int_t sflag=0; + Int_t eflag=0; + + if (mode==0) + { + delete fSigflags; + fSigflags=0; + } + else if (abs(mode)==1) + { + for (Int_t i=1; i<=fSigflags->GetSize(); i++) + { + eflag=GetErrorFlag(i); + SetSigFlags(0,eflag,i); + } + } + else if (abs(mode)==2) + { + for (Int_t j=1; j<=fSigflags->GetSize(); j++) + { + sflag=GetSignalFlag(j); + SetSigFlags(sflag,0,j); + } + } + + if (mode>=0) DeleteWaveform(0); } /////////////////////////////////////////////////////////////////////////// void AliSignal::SetSignal(Double_t sig,Int_t j) { // Store signal value for the j-th (default j=1) slot. -// Note : The first signal slot is at j=1. +// Notes : +// ------- +// 1) The first signal slot is at j=1. +// 2) In case the 'lock' flag was set for the specified slot, the new +// signal value will not be stored. +// One has to unlock the specified slot first in case one really wants +// to overwite the signal value. // In case the value of the index j exceeds the maximum number of reserved // slots for signal values, the number of reserved slots for the // signal values is increased automatically. + if (GetLockValue(j)) return; + if (!fSignals) { fSignals=new TArrayF(j); - ResetSignals(1); + ResetSignals(-1); } Int_t size=fSignals->GetSize(); @@ -357,12 +437,22 @@ 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) { // Store signal value for the name-specified slot. // +// Note : +// ------ +// In case the 'lock' flag was set for the specified slot, the new +// signal value will not be stored. +// One has to unlock the specified slot first in case one really wants +// to overwite the signal value. +// // 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. @@ -370,17 +460,28 @@ void AliSignal::SetSignal(Double_t sig,TString name) // either directly or via a few invokations of GetSlotIndex(). Int_t j=GetSlotIndex(name); - if (j>0) SetSignal(sig,j); + if (j>0) + { + if (!GetLockValue(j)) SetSignal(sig,j); + } } /////////////////////////////////////////////////////////////////////////// void AliSignal::AddSignal(Double_t sig,Int_t j) { // Add value to the signal of the j-th (default j=1) slot. -// Note : The first signal slot is at j=1. +// Notes : +// ------- +// 1) The first signal slot is at j=1. +// 2) In case the 'lock' flag was set for the specified slot, the new +// signal value will not be stored. +// One has to unlock the specified slot first in case one really wants +// to overwite the signal value. // In case the value of the index j exceeds the maximum number of reserved // slots for signal values, the number of reserved slots for the // signal values is increased automatically. + if (GetLockValue(j)) return; + if (!fSignals) { fSignals=new TArrayF(j); @@ -396,12 +497,22 @@ 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) { // Add value to the signal of the name-specified slot. // +// Note : +// ------ +// In case the 'lock' flag was set for the specified slot, the new +// signal value will not be stored. +// One has to unlock the specified slot first in case one really wants +// to overwite the signal value. +// // 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. @@ -409,7 +520,10 @@ void AliSignal::AddSignal(Double_t sig,TString name) // either directly or via a few invokations of GetSlotIndex(). Int_t j=GetSlotIndex(name); - if (j>0) AddSignal(sig,j); + if (j>0) + { + if (!GetLockValue(j)) AddSignal(sig,j); + } } /////////////////////////////////////////////////////////////////////////// Float_t AliSignal::GetSignal(Int_t j,Int_t mode) const @@ -599,15 +713,23 @@ Float_t AliSignal::GetSignal(TString name,Int_t mode) const void AliSignal::SetSignalError(Double_t dsig,Int_t j) { // Store error on the signal for the j-th (default j=1) slot. -// Note : The first signal slot is at j=1. +// Notes : +// ------- +// 1) The first signal slot is at j=1. +// 2) In case the 'lock' flag was set for the specified slot, the new +// signal error value will not be stored. +// One has to unlock the specified slot first in case one really wants +// to overwite the signal error value. // In case the value of the index j exceeds the maximum number of reserved // slots for signal error values, the number of reserved slots for the // signal errors is increased automatically. + if (GetLockValue(j)) return; + if (!fDsignals) { fDsignals=new TArrayF(j); - ResetSignals(2); + ResetSignals(-2); } Int_t size=fDsignals->GetSize(); @@ -618,12 +740,22 @@ 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) { // Store error on the signal for the name-specified slot. // +// Note : +// ------ +// In case the 'lock' flag was set for the specified slot, the new +// signal error value will not be stored. +// One has to unlock the specified slot first in case one really wants +// to overwite the signal error value. +// // 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. @@ -631,7 +763,10 @@ void AliSignal::SetSignalError(Double_t dsig,TString name) // either directly or via a few invokations of GetSlotIndex(). Int_t j=GetSlotIndex(name); - if (j>0) SetSignalError(dsig,j); + if (j>0) + { + if (!GetLockValue(j)) SetSignalError(dsig,j); + } } /////////////////////////////////////////////////////////////////////////// Float_t AliSignal::GetSignalError(Int_t j) const @@ -670,9 +805,16 @@ 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(); @@ -682,7 +824,7 @@ void AliSignal::Data(TString f) const if (strlen(title)) cout << " Title : " << title; cout << endl; cout << " Position"; - AliPosition::Data(f); + AliPosition::Data(f,u); if (fDevice) { const char* devname=fDevice->GetName(); @@ -697,6 +839,9 @@ void AliSignal::Data(TString f) const // 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); } @@ -735,23 +880,10 @@ void AliSignal::List(Int_t j) const } } - Int_t nvalues=GetNvalues(); - Int_t nerrors=GetNerrors(); + Int_t n=GetNslots(); Int_t nlinkslots=0; - if (fLinks) nlinkslots=fLinks->GetMaxColumn(); - Int_t ncalibs=GetNcalflags(); - Int_t ncalfuncs=GetNcalfuncs(); - Int_t ndecalfuncs=GetNdecalfuncs(); - - Int_t n=nvalues; - if (nerrors>n) n=nerrors; + if (GetNlinks()) nlinkslots=fLinks->GetMaxColumn(); if (nlinkslots>n) n=nlinkslots; - if (InheritsFrom("AliDevice")) - { - if (ncalibs>n) n=ncalibs; - if (ncalfuncs>n) n=ncalfuncs; - if (ndecalfuncs>n) n=ndecalfuncs; - } TObject* obj=0; Int_t nrefs=0; @@ -762,28 +894,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=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; } } } @@ -792,28 +929,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=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; } } } @@ -905,19 +1047,249 @@ void AliSignal::ListWaveform(Int_t j) const } } /////////////////////////////////////////////////////////////////////////// +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; +} +/////////////////////////////////////////////////////////////////////////// +void AliSignal::SetSigFlags(Int_t is,Int_t ie,Int_t j) +{ +// 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); +} +/////////////////////////////////////////////////////////////////////////// +Int_t AliSignal::GetSignalFlag(Int_t j) const +{ +// 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; +} +/////////////////////////////////////////////////////////////////////////// +Int_t AliSignal::GetSignalFlag(TString name) const +{ +// 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 +// 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=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 (nGetNrefs(obj); + n=fLinks->GetNrefs(obj); } else { @@ -1210,6 +1584,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. @@ -1225,7 +1607,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); } } } @@ -1242,6 +1624,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); @@ -1271,6 +1676,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. @@ -1305,6 +1718,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); @@ -1356,7 +1792,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 @@ -1412,7 +1855,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 @@ -1428,6 +1878,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); @@ -1602,6 +2064,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.