//------------------------------------------------------------------------------ // Main data classes -- // (C) Piero Giubilato 2008-2010, Berkeley Lab -- //------------------------------------------------------------------------------ //______________________________________________________________________________ // {Trace} // [File name] "data_Frame.cpp" // [Author] "Piero Giubilato" // [Version] "1.0" // [Modified by] "Piero Giubilato" // [Last revision] "31 Jan 2009" // [Language] "C++" // [Compiler] "Visual C++ 9.x" // [Member of] "Cool SEAL" // [Project] "SEAL" // [Description] "Main data classes." // [Key documentation] // "Root user's guide" // "Visual C++ Reference Help" // {Trace} //______________________________________________________________________________ // Overloading check (due to template use) #ifndef data_Frame_C #define data_Frame_C // Standard libs #include #include // Root components #include #include // Application components #include "data_Frame.h" // ***************************************************************************** // **** SPECIAL MEMBERS **** // ***************************************************************************** //______________________________________________________________________________ template data_Frame::data_Frame(): data_Object() { // Provides management for a data_Layer collection. dbg_Print("data_Frame::data_Frame:()", DBG_LVL_ZERO); // Preset data layer_Count(1); } //______________________________________________________________________________ template data_Frame::data_Frame(const data_Frame& ref): data_Object() { // Default copy constructor dbg_Print("data_Frame::data_Frame:(data_Frame*)", DBG_LVL_ZERO); // Preset data data_Copy(ref); } //______________________________________________________________________________ template template data_Frame::data_Frame(const data_Frame& ref): data_Object() { // Casting copy constructor dbg_Print("data_Frame::data_Frame:(data_Frame*)", DBG_LVL_ZERO); // Preset data data_Copy(ref); } //______________________________________________________________________________ template data_Frame::data_Frame(const geom_Frame* ref): data_Object() { // geom_Frame construnctor. This constructor builds the frame in order to // fit the data arrangement of the passed 'ref*' geom_Frame. dbg_Print("data_Frame::data_Frame:(geom_Frame*)", DBG_LVL_ZERO); // Preset data frame_Fit(ref); } //______________________________________________________________________________ template data_Frame::~data_Frame() { // Destructor: frees all allocated memory (by deleting every // sub-object) dbg_Print("data_Frame::~data_Frame:()", DBG_LVL_ZERO); // Delete all layers for (UInt_t i = 0; i < ly_Array.size(); i++) delete ly_Array[i]; } // ***************************************************************************** // **** PRIVATE OBJECT ACCESS **** // ***************************************************************************** //______________________________________________________________________________ template template void data_Frame::data_Copy(const data_Frame& Source) { // Copies the data from another Frame, casting them dbg_Print("data_Frame::data_Copy:(data_Frame&)", DBG_LVL_STEP); // Self copy check if (this == (data_Frame*)&Source) return; // Parent copy data_Object::operator=(Source); // Shallow copy fit_frame_Ref = Source.frame_Fit(); // Deep copy layer_Count(Source.layer_Count()); for (UInt_t i = 0; i < ly_Array.size(); i++) *ly_Array[i] = *(Source.layer(i)); } //______________________________________________________________________________ template template void data_Frame::data_Math(const U& Source, UInt_t Operation) { // Performs algebra with scalars dbg_Print("data_Frame::data_Math:(U&)", DBG_LVL_STEP); // Do it! for (UInt_t l = 0; l < ly_Array.size(); l++) { switch (Operation) { case km_Set: *ly_Array[l] = Source; break; case km_Add: *ly_Array[l] += Source; break; case km_Sub: *ly_Array[l] -= Source; break; case km_Mul: *ly_Array[l] *= Source; break; case km_Div: *ly_Array[l] /= Source; break; // Allowed for scalar only! case km_Sqr: ly_Array[l]->dp_all_Sqr(); break; case km_Pow: ly_Array[l]->dp_all_Pow((Int_t)Source); break; case km_Mir: ly_Array[l]->dp_all_Mir((T)Source); break; } } } //______________________________________________________________________________ template template void data_Frame::data_Math(const data_Layer& Source, UInt_t Operation) { // Performs algebra with data_layers dbg_Print("data_Frame::data_Math:(data_Layer&)", DBG_LVL_STEP); // Do it! for (UInt_t l = 0; l < ly_Array.size(); l++) { switch (Operation) { case km_Set: *ly_Array[l] = Source; break; case km_Add: *ly_Array[l] += Source; break; case km_Sub: *ly_Array[l] -= Source; break; case km_Mul: *ly_Array[l] *= Source; break; case km_Div: *ly_Array[l] /= Source; break; } } } //______________________________________________________________________________ template template void data_Frame::data_Math(const data_Frame& Source, UInt_t Operation) { // Performs algebra with data_Frames dbg_Print("data_Frame::data_Math:(data_Frame&)", DBG_LVL_STEP); // Check for frame dimension UInt_t lyCnt; (Source.layer_Count() < ly_Array.size()) ? lyCnt = Source.layer_Count() : lyCnt = ly_Array.size(); // Do it! for (UInt_t l = 0; l < lyCnt; l++) { switch (Operation) { case km_Set: *ly_Array[l] = *(Source.layer(l)); break; case km_Add: *ly_Array[l] += *(Source.layer(l)); break; case km_Sub: *ly_Array[l] -= *(Source.layer(l)); break; case km_Mul: *ly_Array[l] *= *(Source.layer(l)); break; case km_Div: *ly_Array[l] /= *(Source.layer(l)); break; // Not implemented here! case km_Sqr: ly_Array[l]->dp_all_Sqr(); break; // Not implemented here! case km_Pow: ly_Array[l]->dp_all_Pow(int(Source)); break; } } } //______________________________________________________________________________ template const geom_Frame* data_Frame::frame_Fit() const { // Returns a pointer to the last fitted frame. WARNING: a data_Frame does NOT // guarantees an associated geom_Frame, so this function can returns a NULL // pointer or even a wrong pointer. return fit_frame_Ref; } //______________________________________________________________________________ template void data_Frame::frame_Fit(const geom_Frame* ref) { // Derives the size of the data_Frame from the properties of an // existing geom_Frame object. Pay attention that this method is // provided to give a fast and accurate initialization of the data_Frame, // but it is not a link to the geom_Frame used nor it does check for // any change into the reference geom_Frame. This function call will erase // any data presents into the current data_Frame. // Debug dbg_Print("data_Frame::frame_Fit:(geom_Frame*)", DBG_LVL_STEP); // Checks if there is a valid frame to derive dimensions from. if (ref) { fit_frame_Ref = ref; } else { fit_frame_Ref = NULL; return; } // Sets up the necessary layers layer_Count(ref->layer_Count()); // Sets each layer size accordingly to the related chip geometry for (UInt_t l = 0; l < ly_Array.size(); l++) { // Matches the mapping boundaries for that logical layer layer(l)->dp_Count(ref->layer(l)->dp_col_Count(), ref->layer(l)->dp_row_Count()); // Clear: initializes the layer with all zeroes layer(l)->dp_all_Set(0); } } //______________________________________________________________________________ template UInt_t data_Frame::obj_Type() const { // Returns the object type (the class type itself) return data_Object::kot_Frame; } //______________________________________________________________________________ template UInt_t data_Frame::data_Type() const { // Returns the object data type (the class type itself) return layer(0)->data_Type(); } // ***************************************************************************** // **** LAYERS ACCESS **** // ***************************************************************************** //______________________________________________________________________________ template UInt_t data_Frame::layer_Count() const { // Retrieves the number of layers present into the frame. return ly_Array.size(); } //______________________________________________________________________________ template UInt_t data_Frame::layer_Count(UInt_t layer_Count) { // Sets the whole number of layers present into the frame. Returns the number // of allocated data_Layer. Invoking this method erases all present layers! dbg_Print("data_Frame::layer_Count:(UInt)", DBG_LVL_MAKE); // Release all committed layers for (UInt_t l = 0; l < ly_Array.size(); l++) delete ly_Array[l]; // Preset the vector ly_Array.clear(); ly_Array.reserve(layer_Count); // Add all the needed layers for (UInt_t l = 0; l < layer_Count; l++) ly_Array.push_back(new data_Layer); // Return return ly_Array.size(); } //______________________________________________________________________________ template data_Layer* data_Frame::layer(UInt_t layer_Idx) const { // Retrieves the handle to the specified layer through its index number. if (layer_Idx >= ly_Array.size()) return NULL; // Returns return ly_Array[layer_Idx]; } //______________________________________________________________________________ template UInt_t data_Frame::dp_Count() const { // Gets the total number of data points present into the data_Frame. // Count UInt_t dp_Count = 0; for (UInt_t l = 0; l < ly_Array.size(); l++) dp_Count += layer(l)->dp_Count(); // Returns return dp_Count; } //______________________________________________________________________________ template UInt_t data_Frame::dp_Size() const { // Gets the total size (bytes) of data points present into the data_Frame. return sizeof(T) * dp_Count(); } // ***************************************************************************** // **** DATA ACCESS **** // ***************************************************************************** //______________________________________________________________________________ template void data_Frame::dp_all_Limits(T& min, T& max) const { // Get the maximum value of the frame dbg_Print("data_Frame::dp_all_Limits:()", DBG_LVL_FLOW); // First layer T ly_Min, ly_Max; ly_Array[0]->dp_all_Limits(min, max); // All the others for (UInt_t l = 1; l < ly_Array.size(); l++) { ly_Array[l]->dp_all_Limits(ly_Min, ly_Max); if (ly_Min < min) min = ly_Min; if (ly_Max > max) max = ly_Max; } } //______________________________________________________________________________ template void data_Frame::dp_all_Stat(Double_t& avg, Double_t& sgm) const { // Get statistics about the frame layers dbg_Print("data_Frame::dp_all_Stat:(Double, Double)", DBG_LVL_FLOW); // Returns the minimum value present into the array UInt_t i_Count = 0; Double_t t_Count = 0; Double_t sum2 = 0; avg = 0; sgm = 0; // Through all layers for (UInt_t l = 0; l < ly_Array.size(); l++) { T* lF = ly_Array[l]->dp_Front(); i_Count = ly_Array[l]->dp_Count(); t_Count += i_Count; for (UInt_t i = 0; i < i_Count; i++) { avg += (Double_t)lF[i]; sum2 += pow((Double_t)lF[i], 2); } } // Calculates results sgm = sqrt(sum2 /= t_Count - pow(avg / t_Count, 2)); avg /= t_Count; } //______________________________________________________________________________ template data_Frame& data_Frame::dp_all_Range(T start, T dp_Step, T ly_Step) { // Build a step range; dp_Step is the step between subsequent layer dp, // while lp is the step between the start point of each layers couple. dbg_Print("data_Frame::dp_all_Range:(T, T, T)", DBG_LVL_FLOW); // Sets the value for (UInt_t l = 0; l < ly_Array.size(); l++) { ly_Array[l]->dp_all_Range(start, dp_Step); start += ly_Step; } // Return itself return *this; } // ***************************************************************************** // **** ROOT OVERLOADS **** // ***************************************************************************** //______________________________________________________________________________ template void data_Frame::Dump(UInt_t level) const { // Dumps all the object data into std::out // Shows the header TString space(' ', level); std::cout << space.Data() << "*data_Frame: " << (int*)this << "\n"; std::cout << space.Data() << "class_Ver: " << class_Ver << "\n"; // Shows the parent data_Object::Dump(level + 2); // Shows data members std::cout << space.Data() << "fit_frame_ref: " << fit_frame_Ref << "\n"; std::cout << space.Data() << "layer_Count: " << ly_Array.size() << "\n"; for (UInt_t i = 0; i < ly_Array.size(); i++) ly_Array[i]->Dump(level + 2); } //______________________________________________________________________________ template void data_Frame::Streamer(TBuffer &b) { // Fills the standar root streamer with the layers inside the frame // Read if (b.IsReading()) { // Debug dbg_Print ("data_Frame::Streamer: read call", DBG_LVL_FLOW) // Reads class version UShort_t class_ver_Read = 0; b >> class_ver_Read; // Checks version if (class_ver_Read != class_Ver) { dbg_Print ("data_Frame::Streamer: read: version mismatch", DBG_LVL_WARN) dbg_Value(class_ver_Read, DBG_LVL_WARN); dbg_Value(class_Ver, DBG_LVL_WARN); } // Reads parent class data_Object::Streamer(b); // Reads all the embedded layers UInt_t ly_Count = 0; b >> ly_Count; ly_Array.clear(); for (UInt_t i = 0; i < ly_Count; i++) { TString name("Layer%u", i); ly_Array.push_back(new data_Layer()); ly_Array[i]->Read(name.Data()); } // Writes } else { // Debug dbg_Print ("data_Frame::Streamer: write call",DBG_LVL_FLOW) // Writes class version b << class_Ver; // Writes parent class data_Object::Streamer(b); // Writes all the embedded layers b << ly_Array.size(); for (UInt_t i = 0; i < ly_Array.size(); i++) { TString name("Layer%u", i); ly_Array[i]->Write(name.Data()); } } } // Overloading check #endif