00001 #include "TGet4HitUnpacked.h" 00002 00003 TGet4HitUnpacked::TGet4HitUnpacked( void ) 00004 { 00005 // flags which indicated whether the edge data are set 00006 // are cleared 00007 m_bLeadingEdgeSet = kFALSE; 00008 m_bTrailingEdgeSet = kFALSE; 00009 00010 uc_get4 = 0; 00011 uc_channel = 0; 00012 00013 u_EpochCycleLeading = 0; 00014 u_EpochNoLeadingEdge = 0; 00015 u_TsLeadingEdge = 0; 00016 00017 u_EpochCycleTrailing = 0; 00018 u_EpochNoTrailingEdge = 0; 00019 u_TsTrailingEdge = 0; 00020 } 00021 00022 // Copy constructor, needed for memory reason? 00023 TGet4HitUnpacked & TGet4HitUnpacked::operator=( const TGet4HitUnpacked & hitOriginal ) 00024 { 00025 if( this != &hitOriginal ) 00026 { 00027 this->Clear(); 00028 uc_get4 = hitOriginal.GetGet4Index(); 00029 uc_channel = hitOriginal.GetChannel(); 00030 00031 m_bLeadingEdgeSet = hitOriginal.IsLeadingSet(); 00032 if( kTRUE == m_bLeadingEdgeSet ) 00033 { 00034 u_EpochCycleLeading = hitOriginal.GetEpochCycleLeading(); 00035 u_EpochNoLeadingEdge = hitOriginal.GetEpochLeading(); 00036 u_TsLeadingEdge = hitOriginal.GetTsLeading(); 00037 } 00038 00039 m_bTrailingEdgeSet = hitOriginal.IsLeadingSet(); 00040 if( kTRUE == m_bTrailingEdgeSet ) 00041 { 00042 u_EpochCycleTrailing = hitOriginal.GetEpochCycleTrailing(); 00043 u_EpochNoTrailingEdge = hitOriginal.GetEpochTrailing(); 00044 u_TsTrailingEdge = hitOriginal.GetTsTrailing(); 00045 } 00046 00047 } 00048 return *this; 00049 } 00050 00051 void TGet4HitUnpacked::ClearHit( void ) 00052 { 00053 // flags which indicated whether the edge data are set 00054 // are cleared 00055 m_bLeadingEdgeSet = kFALSE; 00056 m_bTrailingEdgeSet = kFALSE; 00057 00058 uc_get4 = 0; 00059 uc_channel = 0; 00060 00061 u_EpochCycleLeading = 0; 00062 u_EpochNoLeadingEdge = 0; 00063 u_TsLeadingEdge = 0; 00064 00065 u_EpochCycleTrailing = 0; 00066 u_EpochNoTrailingEdge = 0; 00067 u_TsTrailingEdge = 0; 00068 } 00069 00070 00071 #ifndef ROC_GET4_BUILDEVENT 00072 // Definition check because ROOT did not aknowledge roc::message in 00073 // old versions 00074 // Maybe unnecessary 00075 void TGet4HitUnpacked::SetMessage( roc::Message &msgNewEdge, UInt_t uEpoch, UInt_t epochCycleRaw ) 00076 { 00077 // first it is checked whether this is a GET4 data event. 00078 if ( msgNewEdge.getMessageType() == roc::MSG_GET4 ) 00079 { 00080 // getting the edge flag 00081 UInt_t uEdge = msgNewEdge.getGet4Edge(); 00082 if ( uEdge == 0 ) 00083 { 00084 Bool_t bLeadingErrorSet = kFALSE; 00085 if ( m_bLeadingEdgeSet ) 00086 // Error: The trailing edge is already set. 00087 bLeadingErrorSet = kTRUE; // => Continue however 00088 00089 // storing the data 00090 m_bLeadingEdgeSet = kTRUE; 00091 00092 uc_get4 = msgNewEdge.getGet4Number(); 00093 uc_channel = msgNewEdge.getGet4ChNum(); 00094 u_EpochNoLeadingEdge = uEpoch; 00095 u_EpochCycleLeading = epochCycleRaw; 00096 u_TsLeadingEdge = msgNewEdge.getGet4Ts(); 00097 00098 if ( m_bTrailingEdgeSet ) 00099 { 00100 // Time Gating 00101 if( TIME_GATE*EPOCH_IN_NS < this->GetTOT() ) 00102 { 00103 Double_t temptot = this->GetTOT(); 00104 m_bTrailingEdgeSet = kFALSE; 00105 // throw CEOutOfTimeGate(); 00106 throw CEOutOfTimeGateDetail( temptot ); 00107 } 00108 00109 if( this->GetTOT() < -0.00001) 00110 { 00111 Double_t temptot = this->GetTOT(); 00112 m_bTrailingEdgeSet = kFALSE; 00113 // throw CEGivesNegativeToT(); 00114 throw CEGivesNegativeToTDetail( temptot ); 00115 } 00116 } 00117 00118 if ( kTRUE == bLeadingErrorSet ) 00119 throw CELeadingEdgeAlreadySet(); 00120 } 00121 else 00122 { 00123 if ( m_bTrailingEdgeSet ) 00124 // Error: The trailing edge is already set. 00125 throw CETrailingEdgeAlreadySet(); 00126 00127 // storing the data 00128 m_bTrailingEdgeSet = kTRUE; 00129 00130 uc_get4 = msgNewEdge.getGet4Number(); 00131 uc_channel = msgNewEdge.getGet4ChNum(); 00132 u_EpochNoTrailingEdge = uEpoch; 00133 u_EpochCycleTrailing = epochCycleRaw; 00134 u_TsTrailingEdge = msgNewEdge.getGet4Ts(); 00135 00136 if ( m_bLeadingEdgeSet ) 00137 { 00138 // Time Gating 00139 if( TIME_GATE*EPOCH_IN_NS < this->GetTOT() ) 00140 { 00141 Double_t temptot = this->GetTOT(); 00142 m_bLeadingEdgeSet = kFALSE; 00143 // throw CEOutOfTimeGate(); 00144 throw CEOutOfTimeGateDetail( temptot ); 00145 } 00146 00147 // Should never happen, bad messages! 00148 if( this->GetTOT() < -0.00001) 00149 { 00150 Double_t temptot = this->GetTOT(); 00151 m_bLeadingEdgeSet = kFALSE; 00152 // throw CEGivesNegativeToT(); 00153 throw CEGivesNegativeToTDetail( temptot ); 00154 } 00155 } 00156 } 00157 } 00158 else 00159 { 00160 throw CENoGET4DataEvent(msgNewEdge.getMessageType()); 00161 } 00162 } 00163 #endif // ROC_GET4_BUILDEVENT 00164 00165 Bool_t TGet4HitUnpacked::Complete( void ) const 00166 { 00167 // The hit information is complete when leading and 00168 // trailing edge information are set. 00169 return m_bLeadingEdgeSet && m_bTrailingEdgeSet; 00170 } 00171 00172 Double_t TGet4HitUnpacked::GetTOT( void ) const 00173 { 00174 // calculation of time over threshold is only possible 00175 // if the hit information is complete. 00176 if ( Complete() ) 00177 { 00178 // Time over threshold is the difference between timestamps of 00179 // trailing and leading edge multiplied by 0.05 ns. 00180 Double_t dToT = BIN_SIZE_IN_NS * (Double_t) ( (Double_t) u_TsTrailingEdge - 00181 (Double_t)u_TsLeadingEdge ); 00182 // When leading and trailing edge are not in the same epoch 00183 // the time over threshold has to be corrected 00184 if ( u_EpochNoLeadingEdge != u_EpochNoTrailingEdge ) 00185 { 00186 if( u_EpochCycleLeading != u_EpochCycleTrailing ) 00187 { 00188 dToT += EPOCH_IN_NS * (Double_t) ( (Double_t)u_EpochNoTrailingEdge - 00189 (Double_t)u_EpochNoLeadingEdge + 00190 (Double_t)CYCLE_IN_EPOCHS * (Double_t) ( (Double_t)u_EpochCycleTrailing - 00191 (Double_t)u_EpochCycleLeading ) ); 00192 } 00193 else 00194 { 00195 dToT += EPOCH_IN_NS * (Double_t) ( (Double_t)u_EpochNoTrailingEdge - 00196 (Double_t)u_EpochNoLeadingEdge ); 00197 } 00198 } 00199 // returns tot in ns. 00200 return dToT; 00201 } 00202 else 00203 throw CEHitIsNotComplete(); 00204 } 00205 Int_t TGet4HitUnpacked::GetRawTOT( void ) const 00206 { 00207 // calculation of time over threshold is only possible 00208 // if the hit information is complete. 00209 if ( Complete() ) 00210 { 00211 // Time over threshold is the difference between timestamps of 00212 // trailing and leading edge multiplied by 0.05 ns. 00213 Int_t iToT = (Int_t) ( (Int_t) u_TsTrailingEdge - 00214 (Int_t)u_TsLeadingEdge ); 00215 // When leading and trailing edge are not in the same epoch 00216 // the time over threshold has to be corrected 00217 if ( u_EpochNoLeadingEdge != u_EpochNoTrailingEdge ) 00218 { 00219 if( u_EpochCycleLeading != u_EpochCycleTrailing ) 00220 { 00221 iToT += EPOCH_IN_BINS * (Int_t) ( (Int_t)u_EpochNoTrailingEdge - 00222 (Int_t)u_EpochNoLeadingEdge + 00223 CYCLE_IN_EPOCHS * (Int_t) ( (Int_t)u_EpochCycleTrailing - 00224 (Int_t)u_EpochCycleLeading ) ); 00225 } 00226 else 00227 { 00228 iToT += EPOCH_IN_BINS * (Int_t) ( (Int_t)u_EpochNoTrailingEdge - 00229 (Int_t)u_EpochNoLeadingEdge ); 00230 } 00231 } 00232 // returns tot in bin. 00233 return iToT; 00234 } 00235 else 00236 throw CEHitIsNotComplete(); 00237 } 00238 00239 Double_t TGet4HitUnpacked::Spacing( const TGet4HitUnpacked &hitFollowing ) const 00240 { 00241 // calculation of pulse spacing is only possible 00242 // if the hit information of both hits is complete. 00243 if ( Complete() && hitFollowing.Complete() ) 00244 { 00245 // calculation is the same like for time over threshold 00246 Double_t dSpacing = BIN_SIZE_IN_NS * 00247 (Double_t) ( (Double_t)hitFollowing.u_TsLeadingEdge - 00248 (Double_t)u_TsLeadingEdge ); 00249 if ( u_EpochNoLeadingEdge != hitFollowing.u_EpochNoLeadingEdge ) 00250 { 00251 dSpacing += EPOCH_IN_NS * (Double_t) ( (Double_t)hitFollowing.u_EpochNoLeadingEdge - 00252 (Double_t)u_EpochNoLeadingEdge ); 00253 if( u_EpochCycleLeading != hitFollowing.u_EpochCycleLeading ) 00254 { 00255 dSpacing += EPOCH_IN_NS * (Double_t)CYCLE_IN_EPOCHS 00256 * (Double_t) ( (Double_t)hitFollowing.u_EpochCycleLeading - 00257 (Double_t)u_EpochCycleLeading ) ; 00258 } 00259 } 00260 // returns pulse spacing in ns. 00261 return dSpacing; 00262 } 00263 else 00264 throw CEHitIsNotComplete(); 00265 } 00266 00267 Int_t TGet4HitUnpacked::CyclesDiff( const TGet4HitUnpacked &hitFollowing ) const 00268 { 00269 return (Int_t) ( (Int_t)hitFollowing.u_EpochCycleLeading - (Int_t)u_EpochCycleLeading ) ; 00270 } 00271 Int_t TGet4HitUnpacked::EpochsDiff( const TGet4HitUnpacked &hitFollowing ) const 00272 { 00273 return (Int_t) ( (Int_t)hitFollowing.u_EpochNoLeadingEdge - (Int_t)u_EpochNoLeadingEdge ) ; 00274 } 00275 00276 UChar_t TGet4HitUnpacked::GetGet4Index() const 00277 { 00278 return uc_get4; 00279 } 00280 UChar_t TGet4HitUnpacked::GetChannel() const 00281 { 00282 return uc_channel; 00283 } 00284 UInt_t TGet4HitUnpacked::GetFullChan() const 00285 { 00286 return ((UInt_t)uc_get4)*4 + (UInt_t)uc_channel; 00287 } 00288 UInt_t TGet4HitUnpacked::GetEpochCycleLeading() const 00289 { 00290 return u_EpochCycleLeading; 00291 } 00292 UInt_t TGet4HitUnpacked::GetEpochLeading() const 00293 { 00294 return u_EpochNoLeadingEdge; 00295 } 00296 UInt_t TGet4HitUnpacked::GetTsLeading() const 00297 { 00298 return u_TsLeadingEdge; 00299 } 00300 UInt_t TGet4HitUnpacked::GetEpochCycleTrailing() const 00301 { 00302 return u_EpochCycleTrailing; 00303 } 00304 UInt_t TGet4HitUnpacked::GetEpochTrailing() const 00305 { 00306 return u_EpochNoTrailingEdge; 00307 } 00308 UInt_t TGet4HitUnpacked::GetTsTrailing() const 00309 { 00310 return u_TsTrailingEdge; 00311 } 00312 Bool_t TGet4HitUnpacked::IsLeadingSet() const 00313 { 00314 return m_bLeadingEdgeSet; 00315 } 00316 Bool_t TGet4HitUnpacked::IsTrailingSet() const 00317 { 00318 return m_bTrailingEdgeSet; 00319 } 00320 00321 00322 void TGet4HitUnpacked::SetGet4Index(UChar_t get4_indexIn) 00323 { 00324 uc_get4 = get4_indexIn; 00325 return ; 00326 } 00327 void TGet4HitUnpacked::SetChannel(UChar_t channelIn) 00328 { 00329 uc_channel = channelIn; 00330 return ; 00331 } 00332 void TGet4HitUnpacked::SetFullChan(UInt_t fullChanIn) 00333 { 00334 uc_get4 = (UChar_t)(fullChanIn/4); 00335 uc_channel = (UChar_t)(fullChanIn%4); 00336 return ; 00337 } 00338 // Used normally only for EXT_SYNC messages 00339 void TGet4HitUnpacked::SetEpochLeading(UInt_t epochLeadingEdgeIn, UInt_t epochCycleIn) 00340 { 00341 m_bLeadingEdgeSet = kTRUE; 00342 m_bTrailingEdgeSet = kTRUE; 00343 u_EpochNoLeadingEdge = epochLeadingEdgeIn; 00344 u_EpochCycleLeading = epochCycleIn; 00345 return ; 00346 } 00347 void TGet4HitUnpacked::SetTsLeading(UInt_t tsLeadingIn) 00348 { 00349 u_TsLeadingEdge = tsLeadingIn; 00350 return ; 00351 } 00352 00353 Int_t TGet4HitUnpacked::EpochEdgesDiff() 00354 { 00355 // Just return the distance in terms of Epochs nb between the 2 00356 // edge messages 00357 if ( this->Complete() ) 00358 return ((Int_t)u_EpochNoTrailingEdge - (Int_t)u_EpochNoLeadingEdge 00359 + CYCLE_IN_EPOCHS * (Int_t) ( (Int_t)u_EpochCycleTrailing - 00360 (Int_t)u_EpochCycleLeading ) ); 00361 else 00362 throw CEHitIsNotComplete(); 00363 } 00364 00365 00366 /* This is the function used to sort Hits in a list in 00367 * function TimeOrderBlock 00368 * For this, it compares 00369 * 1) The epoch index cycles 00370 * 2) The epoch indexes 00371 * 3) the leading edge timestamps 00372 */ 00373 bool TGet4HitUnpacked::operator<(const TGet4HitUnpacked &rhs) const 00374 { 00375 // Epoch counter reset between the 2 hits ? 00376 if( GetEpochCycleLeading() < rhs.GetEpochCycleLeading() ) 00377 return true; 00378 else if( GetEpochCycleLeading() > rhs.GetEpochCycleLeading() ) 00379 return false; 00380 // Same cycle => Clock counter reset between the 2 hits ? (epoch 00381 else if( GetEpochLeading() < rhs.GetEpochLeading() ) 00382 return true; 00383 else if( GetEpochLeading() > rhs.GetEpochLeading() ) 00384 return false; 00385 // Same cycle and same epoch! 00386 else if( 0.0 <= Spacing(rhs) ) 00387 return true; 00388 else return false; 00389 }