Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/Makefile
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/Makefile	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/Makefile	(revision 14268)
@@ -0,0 +1,10 @@
+all: comp1 comp2
+
+comp1 : comp1.cpp fits.h izstream.h helper.hxx helper.o
+	g++ comp1.cpp helper.o -lz -o comp1
+	
+comp2 : comp2.cpp fits.h izstream.h helper.hxx helper.o
+	g++ comp2.cpp helper.o -lz -o comp2
+	
+helper.o: helper.cpp helper.hxx
+	g++ -c helper.cpp -o helper.o
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/comp1.cpp
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/comp1.cpp	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/comp1.cpp	(revision 14268)
@@ -0,0 +1,461 @@
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string.h>
+
+// I will use the fits class by TB for reading the interesting data from the files
+
+#include "izstream.h"
+
+#define HAVE_ZLIB
+#include "fits.h"
+
+#include "helper.hxx"
+
+using namespace std;
+
+ifstream::pos_type size;
+char * memblock;
+
+int main (int argc, char * argv[]) {
+
+    char * data_file_name = "20120712_004.fits";
+    char * calib_file_name ="20120712_003.drs.fits.gz";
+    char * out_file_name = NULL;
+    out_file_name = new char[strlen(data_file_name)+4];
+    strcpy(out_file_name, data_file_name);
+    strcpy(out_file_name+strlen(data_file_name),".fc");
+    out_file_name[strlen(data_file_name)+3] = 0;
+
+    
+    //=========================================================================
+    // CALIBRATION CONSTANTS
+    //=========================================================================
+    fits * calib =new fits(calib_file_name);
+    calib->PrintKeys();
+    calib->PrintColumns();
+
+    int size_of_offset = 1440*1024;
+    float * offset_mV = new float[size_of_offset];
+    short * offset = new short[size_of_offset];
+    calib->SetPtrAddress("BaselineMean",offset_mV, size_of_offset);
+
+    calib->GetNextRow();
+    for (int i =0 ; i<size_of_offset; i++)
+    {
+        offset[i] = short(offset_mV[i] / 2000. * 4096 - 0.5);
+    }
+    cout << endl;
+    delete[] offset_mV;
+    delete calib;
+    calib = NULL;
+    //=========================================================================
+    // END OF                CALIBRATION CONSTANTS
+    //=========================================================================
+    
+    
+    //=========================================================================
+    // DATA FILE - with FITS class
+    //=========================================================================
+    
+    fits * datafits = new fits(data_file_name);
+    
+    datafits->PrintKeys();
+    datafits->PrintColumns();
+    
+    int nevents = (int)datafits->GetNumRows();
+    int roi = (int)datafits->GetInt("NROI");
+    int npixel = (int)datafits->GetInt("NPIX");
+    int event_size = npixel * roi;
+
+
+    
+    short *event = new short[event_size];
+    short *sc = new short[npixel];
+    datafits->SetPtrAddress("Data",event, event_size );
+    datafits->SetPtrAddress("StartCellData",sc, npixel );
+    
+    short first_word;
+    short *diffs = new short[event_size-1];
+    short *sizes = new short[event_size-1];
+    
+    //=========================================================================
+    // DATA FILE - with ISTREAM
+    //=========================================================================
+    ifstream datafile (data_file_name, ios::in|ios::binary);
+    ofstream out (out_file_name, ios::out|ios::binary|ios::trunc);
+    helper h(&datafile, &out);
+    
+    
+    if (datafile.is_open() && out.is_open())
+    {
+        // create our own header
+//        out.write( "FACT_COMPRESS                                                                   ", 80);
+//        out.write( "END.                                                                            ", 80);
+        
+        h.copy_ascii_header();
+        
+        for ( int event_id = 0 ; event_id < nevents; event_id++)
+        {
+            h.copy_event_header();
+            printf("last event header @: 0x%10X \n", h.event_header_start);
+
+
+            // jump over npixel * roi * shorts
+            datafile.seekg( datafile.tellg() + long(npixel * roi * sizeof(short)) , ios::beg);
+            // since the data is stored big-endian in the FITS file, I can't memcopy it .. 
+            // have to use the methods of the fits-class
+            
+            datafits->GetNextRow();
+            
+            // perform a little DRS calibration
+            for ( int pix=0; pix<npixel; pix++){
+                short *pevt = event+pix*roi;
+                short cell = sc[pix];
+                short *poff = offset+pix*1024;
+                
+                for ( int sl=0 ; sl<roi; sl++)
+                {
+                    pevt[sl] -= poff[(sl+cell)%1024];
+                }                
+            
+            }
+            
+            
+            first_word = event[0];
+            for (int i=0; i<event_size-1; i++)    
+            {
+                diffs[i] = event[i+1]-event[i];
+                if (diffs[i] >= -8 && diffs[i] <= 7)
+                    sizes[i] = 4; 
+                else if (diffs[i] >= -16 && diffs[i] <= 15)
+                    sizes[i] = 5;
+                else if (diffs[i] >= -32 && diffs[i] <= 31)
+                    sizes[i] = 6; 
+                else if (diffs[i] >= -128 && diffs[i] <= 127)
+                    sizes[i] = 8;
+                else if (diffs[i] >= -256 && diffs[i] <=255)
+                    sizes[i] = 9;
+                else if (diffs[i] >= -512 && diffs[i] <= 511)
+                    sizes[i] = 10;
+                else if (diffs[i] >= -1024 && diffs[i] <= 1023)
+                    sizes[i] = 11;
+                else if (diffs[i] >= -2048 && diffs[i] <= 2047)
+                    sizes[i] = 12;
+                else
+                    sizes[i] = 16;
+                /*      
+                if (diffs[i] >= -128 && diffs[i] <= 127)
+                    sizes[i] = 8;
+                else
+                    sizes[i] = 16;
+                */
+            }
+
+            
+
+            short last_size = 77;            
+            long long cevts = sizeof(first_word)*8;
+            vector< vector<int> > groups;
+            for (int i=0; i<event_size-1; i++)
+            {
+                if (last_size != sizes[i])
+                {
+                    vector<int> dummy;
+                    groups.push_back( dummy );
+                    last_size = sizes[i];
+                }
+                groups.back().push_back(i);
+            }
+            
+            // calc compressed event size
+            cevts = sizeof(first_word)*8;
+            for (int i=0; i<groups.size(); i++)
+            {
+                cevts += 16; // so called group header 2 bytes long                
+                cevts += groups[i].size() * sizes[groups[i][0]];
+            }
+            cout << double(cevts)/8.<< endl;
+            cout << "\t number of groups:" << groups.size() << endl;
+                      
+  
+            cout << "optimizing..." << endl;
+            int was_better = 1;
+            long long last_cevts = cevts;
+            while ( was_better )
+            {
+        
+               for (int i=0; i<groups.size(); i++)
+               {
+                   if ((groups[i].size() == 1) && (sizes[groups[i][0]] < sizes[groups[i+1][0]]) )
+                   {
+                       // put the group into the right neighbor
+                       // increase the sizes of this group
+                       for(int j=0; j<groups[i].size(); j++)
+                       {
+                           sizes[groups[i][j]] = sizes[groups[i+1][0]];
+                       }
+                       // put the groups togther
+                       groups[i].insert(groups[i].end(), groups[i+1].begin(), groups[i+1].end());
+                       // erase the right group
+                       groups.erase(groups.begin()+i+1);
+                       break;   
+                   }
+               }
+
+               cevts = sizeof(first_word)*8;
+               for (int i=0; i<groups.size(); i++)
+               {
+                   cevts += 16; // so called group header 2 bytes long                
+                   cevts += groups[i].size() * sizes[groups[i][0]];
+               }
+//               cout << double(cevts)/8.<< endl;
+            
+            if (cevts < last_cevts)
+                was_better = 1;
+             else
+                was_better = 0;
+            last_cevts =  cevts;
+            }           
+            
+            cout << double(cevts)/8.<< endl;
+            cout << "\t number of groups:" << groups.size() << endl;
+            
+            cout << "optimizing..." << endl;
+            was_better = 1;
+            last_cevts = cevts;
+            while ( was_better )
+            {
+        
+               for (int i=0; i<groups.size(); i++)
+               {
+                   if ((groups[i].size() == 2) && (sizes[groups[i][0]] < sizes[groups[i+1][0]]) )
+                   {
+                       // put the group into the right neighbor
+                       // increase the sizes of this group
+                       for(int j=0; j<groups[i].size(); j++)
+                       {
+                           sizes[groups[i][j]] = sizes[groups[i+1][0]];
+                       }
+                       // put the groups togther
+                       groups[i].insert(groups[i].end(), groups[i+1].begin(), groups[i+1].end());
+                       // erase the right group
+                       groups.erase(groups.begin()+i+1);
+                       break;   
+                   }
+               }
+
+               cevts = sizeof(first_word)*8;
+               for (int i=0; i<groups.size(); i++)
+               {
+                   cevts += 16; // so called group header 2 bytes long                
+                   cevts += groups[i].size() * sizes[groups[i][0]];
+               }
+//               cout << double(cevts)/8.<< endl;
+            
+            if (cevts < last_cevts)
+                was_better = 1;
+             else
+                was_better = 0;
+            last_cevts =  cevts;
+            }           
+            
+            cout << double(cevts)/8.<< endl;
+            cout << "\t number of groups:" << groups.size() << endl;
+            
+            cout << "optimizing..." << endl;
+            was_better = 1;
+            last_cevts = cevts;
+            while ( was_better )
+            {
+        
+               for (int i=0; i<groups.size(); i++)
+               {
+                   if ((groups[i].size() == 3) && (sizes[groups[i][0]] < sizes[groups[i+1][0]]) )
+                   {
+                       // put the group into the right neighbor
+                       // increase the sizes of this group
+                       for(int j=0; j<groups[i].size(); j++)
+                       {
+                           sizes[groups[i][j]] = sizes[groups[i+1][0]];
+                       }
+                       // put the groups togther
+                       groups[i].insert(groups[i].end(), groups[i+1].begin(), groups[i+1].end());
+                       // erase the right group
+                       groups.erase(groups.begin()+i+1);
+                       break;   
+                   }
+               }
+
+               cevts = sizeof(first_word)*8;
+               for (int i=0; i<groups.size(); i++)
+               {
+                   cevts += 16; // so called group header 2 bytes long                
+                   cevts += groups[i].size() * sizes[groups[i][0]];
+               }
+//               cout << double(cevts)/8.<< endl;
+            
+            if (cevts < last_cevts)
+                was_better = 1;
+             else
+                was_better = 0;
+            last_cevts =  cevts;
+            }           
+            
+            cout << double(cevts)/8.<< endl;
+            cout << "\t number of groups:" << groups.size() << endl;
+            
+            int min = 100;
+            int argmin;
+            int minsize;
+            for (int i=0; i<groups.size(); i++)
+            {
+                if (groups[i].size() < min)
+                {
+                    min = groups[i].size();
+                    argmin = i;
+                    minsize = sizes[groups[i][0]];
+                }
+            }
+            cout << "min:" << min << endl;
+            cout << "argmin:" << argmin << endl;
+            cout << "minsize:" << minsize << endl;
+            
+            
+            return 0;
+/*                
+                // calculate group sizes
+                int counter = 0;
+                unsigned char last_size = sizes[0];
+                vector<int> group_sizes;
+                vector<unsigned char> groups;
+                
+                for (int i=0 ; i < diff_size; i++)
+                {
+                    
+                    if (sizes[i] != last_size)
+                    {
+                        group_sizes.push_back( counter );
+                        groups.push_back( last_size );
+                        last_size = sizes[i];
+                    }
+                    counter++;
+                }
+                groups.push_back( last_size );
+                group_sizes.push_back( counter );
+                
+
+                // measure how large the stuff, is
+                int cs =0;
+                // for all groups write header and group
+                short header = 0;
+                int diff_index = 0;
+                for ( int i = 0 ; i < (int)groups.size() ; i++)
+                {
+                    // write header
+                    if (groups[i] == 8)
+                    {
+                        header = short(group_sizes[i]);
+                    }
+                    else
+                    {
+                        header = 0x8000 | short(group_sizes[i] );
+                    }
+                    cs += sizeof(short);
+
+                    // write group
+                    if (groups[i] == 8)
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            cs += 1;
+                        }
+                    }
+                    else
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            cs += 2;
+                        }
+                    }
+                }
+                //cout << "compressed size:" << cs << endl;
+                out.write( (char*)&cs, sizeof(cs));
+
+                cout << "sizeof(cs):" << sizeof(cs) << endl;
+
+                // write the first short
+                out.write(memblock, 1*sizeof(short) );
+                printf("first short: 0x%X \t %d \n", ( (short*)memblock )[0], ( (short*)memblock )[0] );
+                // for all groups write header and group
+                header = 0;
+                diff_index = 0;
+                for ( int i = 0 ; i < (int)groups.size() ; i++)
+                {
+                    // write header
+                    if (groups[i] == 8)
+                    {
+                        header = short(group_sizes[i]);
+                    }
+                    else
+                    {
+                        header = 0x8000 | short(group_sizes[i] );
+                    }
+                    out.write( (char*)&header, sizeof(short));
+                    
+                    // write group
+                    if (groups[i] == 8)
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            out.write( (char*)&(diffs[diff_index++]), 1);
+                        }
+                    }
+                    else
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            out.write( (char*)&(diffs[diff_index++]), 2);
+                        }
+                    }
+                }
+                
+                //out.write(memblock, data_size*sizeof(short) );
+                
+                delete[] memblock;
+                delete[] diffs;
+                delete[] sizes;
+*/
+            //}
+            
+        }
+        cout << "finished with 1000 events." << endl;
+        long after_address = datafile.tellg();
+        datafile.seekg (0, ios::end);
+        long end = datafile.tellg();
+        datafile.seekg (after_address, ios::beg);
+        
+        cout << "between last event and end:" << end - after_address << endl;
+        // read the last piece...
+        const int rest_size = end-after_address;
+        char * memblock2 = new char [rest_size];
+        datafile.read(memblock2, rest_size);
+        cout << "first char in memblock: " << int(memblock2[0]) << endl;
+        char lastchar = memblock2[0];
+        for (int i =0 ; i<rest_size; i++)
+        {
+            if (memblock2[i] != lastchar)
+            {
+                cout << "new char at: " << i << " with value:" << int(memblock[0]) << endl;
+                lastchar = memblock2[i];
+            }
+        }
+        
+        out.write(memblock2, rest_size);
+        delete[] memblock2;
+        
+        
+        datafile.close();
+        out.close();
+  } //end of if file open
+} //end of main
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/comp2.cpp
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/comp2.cpp	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/comp2.cpp	(revision 14268)
@@ -0,0 +1,390 @@
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string.h>
+#include <math.h>
+
+// I will use the fits class by TB for reading the interesting data from the files
+
+#include "izstream.h"
+
+#define HAVE_ZLIB
+#include "fits.h"
+
+#include "helper.hxx"
+
+using namespace std;
+
+ifstream::pos_type size;
+char * memblock;
+
+void make_groups( vector<int>& group_starts , vector<int>& group_length, short * sizes, int len_sizes, int roi);
+long get_event_size( vector<int>& gs, vector<int>& gl, short * sizes);
+
+int main (int argc, char * argv[]) {
+
+    char * data_file_name = "20120712_004.fits";
+    char * calib_file_name ="20120712_003.drs.fits.gz";
+    char * out_file_name = NULL;
+    out_file_name = new char[strlen(data_file_name)+4];
+    strcpy(out_file_name, data_file_name);
+    strcpy(out_file_name+strlen(data_file_name),".fc");
+    out_file_name[strlen(data_file_name)+3] = 0;
+
+    
+    //=========================================================================
+    // CALIBRATION CONSTANTS
+    //=========================================================================
+    fits * calib =new fits(calib_file_name);
+    calib->PrintKeys();
+    calib->PrintColumns();
+
+    int size_of_offset = 1440*1024;
+    float * offset_mV = new float[size_of_offset];
+    short * offset = new short[size_of_offset];
+    calib->SetPtrAddress("BaselineMean",offset_mV, size_of_offset);
+
+    calib->GetNextRow();
+    for (int i =0 ; i<size_of_offset; i++)
+    {
+        offset[i] = short(offset_mV[i] / 2000. * 4096 - 0.5);
+    }
+    cout << endl;
+    delete[] offset_mV;
+    delete calib;
+    calib = NULL;
+    //=========================================================================
+    // END OF                CALIBRATION CONSTANTS
+    //=========================================================================
+    
+    
+    //=========================================================================
+    // DATA FILE - with FITS class
+    //=========================================================================
+    
+    fits * datafits = new fits(data_file_name);
+    
+    datafits->PrintKeys();
+    datafits->PrintColumns();
+    
+    int nevents = (int)datafits->GetNumRows();
+    int roi = (int)datafits->GetInt("NROI");
+    int npixel = (int)datafits->GetInt("NPIX");
+    int event_size = npixel * roi;
+
+
+    
+    short *event = new short[event_size];
+    short *sc = new short[npixel];
+    datafits->SetPtrAddress("Data",event, event_size );
+    datafits->SetPtrAddress("StartCellData",sc, npixel );
+    
+    short first_word;
+    short *diffs = new short[event_size-1];
+    short *sizes = new short[event_size-1];
+    
+    //=========================================================================
+    // DATA FILE - with ISTREAM
+    //=========================================================================
+    ifstream datafile (data_file_name, ios::in|ios::binary);
+    ofstream out (out_file_name, ios::out|ios::binary|ios::trunc);
+    helper h(&datafile, &out);
+    
+    
+    if (datafile.is_open() && out.is_open())
+    {
+        // create our own header
+//        out.write( "FACT_COMPRESS                                                                   ", 80);
+//        out.write( "END.                                                                            ", 80);
+        
+//        h.copy_ascii_header();
+        
+        for ( int event_id = 0 ; event_id < nevents; event_id++)
+        {
+//            h.copy_event_header();
+            printf("last event header @: 0x%10X \n", h.event_header_start);
+
+
+            // jump over npixel * roi * shorts
+            datafile.seekg( datafile.tellg() + long(npixel * roi * sizeof(short)) , ios::beg);
+            // since the data is stored big-endian in the FITS file, I can't memcopy it .. 
+            // have to use the methods of the fits-class
+
+            datafits->GetNextRow();
+
+            // perform a little DRS calibration
+            for ( int pix=0; pix<npixel; pix++){
+                short *pevt = event+pix*roi;
+                short cell = sc[pix];
+                short *poff = offset+pix*1024;
+                
+                for ( int sl=0 ; sl<roi; sl++)
+                {
+                    pevt[sl] -= poff[(sl+cell)%1024];
+                }                
+            
+            }
+
+            
+            first_word = event[0];
+            //event_size = 100;
+            
+            short d;
+            for (int i=0; i<event_size-1; i++)    
+            {
+                diffs[i] = event[i+1]-event[i];
+                d = diffs[i];
+                for (int b =4; b<20; b++)
+                {
+                    if ( (d >= -1*(1<<b)) && (d <= (1<<b)-1))
+                    {
+                        sizes[i] = b+1;
+                        break;
+                    }
+                }
+            }
+
+            vector<int> gs;
+            vector<int> gl;
+            make_groups( gs , gl, sizes, event_size-1, event_size);            
+
+            long cevts = get_event_size( gs,gl, sizes);            
+
+            cout << cevts << endl;
+            cout << "number of groups:" << gs.size() << endl;
+
+            // write the length of the event
+            out.write( (char*) &cevts, sizeof(cevts) );
+            // write the event to disk
+            out.write( (char*)&first_word, sizeof(first_word));
+            unsigned short header;
+            for (int g=0; g<gs.size(); g++){
+                
+                if (g<50)
+    //                printf("group: %3d length: %4d -- size: %2d ", g, gl[g], sizes[gs[g]]);
+
+                header = (unsigned short)gl[g] & 0x0FFF;
+                header |= (sizes[gs[g]]-5) << 12;
+
+                out.write( (char*)&header, sizeof(header));
+                int group_size = ceil((gl[g]*sizes[gs[g]])/8.);
+                if (g<50)
+  //                  printf("group_size: %4d ", group_size);
+                
+                int size = sizes[gs[g]];
+                unsigned char * buffer = new unsigned char[ group_size ];
+                for (int i=0; i<group_size; i++) buffer[i] = 0;
+                unsigned short *data = (unsigned short *)diffs;
+
+                int *bs = new int[gl[g]];
+                int *Bs = new int[gl[g]];
+
+                for (int i=0; i<gl[g] ;i++)
+                {
+                    int bit_pos = ((i+1)*size)-1;
+                    Bs[i] = bit_pos/8;
+                    bs[i] = bit_pos%8;
+                }
+                
+                for (int i=0; i<gl[g] ;i++)
+                {
+                    int ii = i+gs[i];
+                    unsigned char dat = (unsigned char)(diffs[ii]);
+                    if (bs[i]+1 >= size) // diff entry fits in one byte
+                    {
+                        buffer[Bs[i]] |= dat <<(bs[i]+1-size);
+                    }
+                    else // entry is distributed over two bytes
+                    {
+                        buffer[Bs[i]]   |= dat>>(size - bs[i]+1);
+                        buffer[Bs[i-1]] |= dat<<(8-size - bs[i]+1);
+                    }
+                }
+                delete[] bs;
+                delete[] Bs;
+                if (g<50)
+                {
+                    int tellp = out.tellp();
+//                    printf("start_addres: 0x%8X\n", tellp);
+                }
+
+                
+                out.write( (char*)buffer, group_size);
+                delete[] buffer;
+            
+            }
+
+
+
+            return 0;
+/*                
+                
+
+                // measure how large the stuff, is
+                int cs =0;
+                // for all groups write header and group
+                short header = 0;
+                int diff_index = 0;
+                for ( int i = 0 ; i < (int)groups.size() ; i++)
+                {
+                    // write header
+                    if (groups[i] == 8)
+                    {
+                        header = short(group_sizes[i]);
+                    }
+                    else
+                    {
+                        header = 0x8000 | short(group_sizes[i] );
+                    }
+                    cs += sizeof(short);
+
+                    // write group
+                    if (groups[i] == 8)
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            cs += 1;
+                        }
+                    }
+                    else
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            cs += 2;
+                        }
+                    }
+                }
+                //cout << "compressed size:" << cs << endl;
+                out.write( (char*)&cs, sizeof(cs));
+
+                cout << "sizeof(cs):" << sizeof(cs) << endl;
+
+                // write the first short
+                out.write(memblock, 1*sizeof(short) );
+                printf("first short: 0x%X \t %d \n", ( (short*)memblock )[0], ( (short*)memblock )[0] );
+                // for all groups write header and group
+                header = 0;
+                diff_index = 0;
+                for ( int i = 0 ; i < (int)groups.size() ; i++)
+                {
+                    // write header
+                    if (groups[i] == 8)
+                    {
+                        header = short(group_sizes[i]);
+                    }
+                    else
+                    {
+                        header = 0x8000 | short(group_sizes[i] );
+                    }
+                    out.write( (char*)&header, sizeof(short));
+                    
+                    // write group
+                    if (groups[i] == 8)
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            out.write( (char*)&(diffs[diff_index++]), 1);
+                        }
+                    }
+                    else
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            out.write( (char*)&(diffs[diff_index++]), 2);
+                        }
+                    }
+                }
+                
+                //out.write(memblock, data_size*sizeof(short) );
+                
+                delete[] memblock;
+                delete[] diffs;
+                delete[] sizes;
+*/
+            //}
+            
+        }
+        cout << "finished with 1000 events." << endl;
+        long after_address = datafile.tellg();
+        datafile.seekg (0, ios::end);
+        long end = datafile.tellg();
+        datafile.seekg (after_address, ios::beg);
+        
+        cout << "between last event and end:" << end - after_address << endl;
+        // read the last piece...
+        const int rest_size = end-after_address;
+        char * memblock2 = new char [rest_size];
+        datafile.read(memblock2, rest_size);
+        cout << "first char in memblock: " << int(memblock2[0]) << endl;
+        char lastchar = memblock2[0];
+        for (int i =0 ; i<rest_size; i++)
+        {
+            if (memblock2[i] != lastchar)
+            {
+                cout << "new char at: " << i << " with value:" << int(memblock[0]) << endl;
+                lastchar = memblock2[i];
+            }
+        }
+        
+        out.write(memblock2, rest_size);
+        delete[] memblock2;
+        
+        
+        datafile.close();
+        out.close();
+  } //end of if file open
+} //end of main
+
+void make_groups( vector<int>& group_starts , vector<int>& group_length, short * sizes, int len_sizes, int roi)
+{
+
+    short * diff_sizes = new short[len_sizes-1];
+
+    for (int i=0; i<len_sizes-1; i++)
+    {
+        diff_sizes[i] = sizes[i+1] - sizes[i];
+    }
+
+    vector<int> gs;
+    vector<int> gl;
+
+
+    gs.push_back(0);
+    for (int i=0; i<len_sizes-1; i++)
+    {
+        if (diff_sizes[i] != 0) 
+        {
+            gs.push_back(i+1);
+        }
+    }
+    gs.push_back(roi-1);
+
+    // make group_length the same length as group_start
+    gl.reserve( gs.size()-1 );
+    for (int i=0; i<gs.size()-1; i++)
+    {
+        gl[i] = gs[i+1] - gs[i];
+    }
+
+    gs.erase(gs.begin()+gs.size()-1);
+
+    group_starts.swap(gs);
+    group_length.swap(gl);
+}
+
+long get_event_size( vector<int>& gs, vector<int>& gl, short * sizes)
+{
+    long bits;
+    // eventsize in bytes
+    long evts = 2; // the first word
+    
+    // gs and gl have equal length
+    for (int i=0; i<gs.size(); i++)
+    {
+        evts += 2; // group header
+        bits = sizes[gs[i]] * gl[i];
+        evts += ceil( bits/8.);
+        
+    }
+    return evts;            
+}
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/compare.cpp
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/compare.cpp	(revision 14267)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/compare.cpp	(revision 14268)
@@ -3,4 +3,6 @@
 #include <iostream>
 #include <fstream>
+#include <stdint.h>
+#include <stdio.h>
 using namespace std;
 
@@ -10,8 +12,8 @@
 char c1,c2;
 
-int main () {
+int main (int argc, char * argv[]) {
     
-    ifstream in1 ("a.fits", ios::in|ios::binary);
-    ifstream in2 ("bla.bin", ios::in|ios::binary);
+    ifstream in1 ( argv[1], ios::in|ios::binary);
+    ifstream in2 ( argv[2], ios::in|ios::binary);
     
     if (in1.is_open() && in2.is_open())
@@ -22,5 +24,5 @@
         end = in1.tellg();
         in1.seekg (0, ios::beg);
-        cout << "a.fits  size:" << end-begin << endl;
+        cout << argv[1] <<" size:" << end-begin << endl;
         
         begin = in2.tellg();
@@ -28,5 +30,5 @@
         end = in2.tellg();
         in2.seekg (0, ios::beg);
-        cout << "bla.bin size:" << end-begin << endl;
+        cout << argv[2] <<" size:" << end-begin << endl;
         
         while ( in1.good() && in2.good() )
@@ -37,6 +39,7 @@
             {
                 cout << "difference found @ adress:" << hex << in1.tellg() << "\t" << in2.tellg() << endl;
-                cout << "in1:" << hex << int(c1) << endl;
-                cout << "in2:" << hex << int(c2) << endl;
+                printf ("%30s \t: 0x%X \n", argv[1] ,uint8_t(c1) );
+                printf ("%30s \t: 0x%X \n", argv[2] ,uint8_t(c2) );
+                break;
             }
         }
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/entropy.cpp
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/entropy.cpp	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/entropy.cpp	(revision 14268)
@@ -0,0 +1,79 @@
+#include <iostream>
+#include <fstream>
+#include <math.h>
+using namespace std;
+
+
+
+int main (int argc, char *argv[]) {
+unsigned char symbol;
+unsigned long *multiples = NULL;
+double *probs = NULL;
+double entropy = 0;
+ofstream outfile;
+ifstream in1;
+long begin,end, size;
+    
+    int bits = sizeof(symbol)*8;
+    long symbols = 1<<bits;
+    multiples = new unsigned long [symbols];
+    probs = new double [symbols];
+
+    if (argc > 1)
+    {
+        in1.open(argv[1], ios::in|ios::binary);
+    }
+    else
+    {
+        return 1;
+    }
+    
+    outfile.open("entropy.txt");
+
+    if (in1.is_open())
+    {                  
+        begin = in1.tellg();
+        in1.seekg (0, ios::end);
+        end = in1.tellg();
+        in1.seekg (0, ios::beg);
+        size = end-begin;
+        outfile << argv[1] << "  size:" << size << endl;
+        outfile << "symbols:" << symbols << endl;
+
+        while ( in1.good())
+        {
+            symbol = in1.get();
+            multiples[symbol]++;
+        }
+
+        outfile << "multiples:" << endl;
+        for (long i=0; i<symbols; i++)
+        {
+            outfile << multiples[i] << "\t";
+            probs[i] = double(multiples[i])/size;
+        }
+        outfile << endl;
+
+        outfile << "probs:" << endl;
+        for (long i=0; i<symbols; i++)
+        {
+            outfile << probs[i] << "\t";
+            if (probs[i] > 0.)
+            {
+                entropy += probs[i] * log(probs[i]);
+            }
+        }
+        entropy /= log(2);
+        outfile << endl;
+
+        outfile << "entropy:" << entropy << endl;
+
+        
+        
+
+        outfile.close();
+        in1.close();
+  } //end of if file open
+  
+return 0;
+} //end of main
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/factblowup.cpp
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/factblowup.cpp	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/factblowup.cpp	(revision 14268)
@@ -0,0 +1,150 @@
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string.h>
+
+// I will use the fits class by TB for reading the interesting data from the files
+
+#include "izstream.h"
+
+#define HAVE_ZLIB
+#include "fits.h"
+
+using namespace std;
+
+ifstream::pos_type size;
+char * memblock;
+
+int main (int argc, char * argv[]) {
+
+
+    if (argc < 3)
+    {
+        cout << "Usage: " << argv[0] << " data-file-name calib-file-name [ouput-file-name]" << endl;
+        cout << "" << endl;
+    }
+    
+    char * data_file_name = argv[1];
+    char * calib_file_name = argv[2];
+    char * out_file_name = 0;
+    if (argc == 4)
+    {
+        out_file_name = argv[3];
+    }
+    else
+    {
+        out_file_name = new char[strlen(data_file_name)+4];
+        strcpy(out_file_name, data_file_name);
+        strcpy(out_file_name+strlen(data_file_name),".uc");
+        out_file_name[strlen(data_file_name)+3] = 0;
+    }
+    
+    
+    
+    
+    //=========================================================================
+    // CALIBRATION CONSTANTS
+    //=========================================================================
+    fits * calib =new fits(calib_file_name);
+    calib->PrintKeys();
+    calib->PrintColumns();
+
+    int size_of_offset = 1440*1024;
+    float * offset_mV = new float[size_of_offset];
+    short * offset = new short[size_of_offset];
+    calib->SetPtrAddress("BaselineMean",offset_mV, size_of_offset);
+
+    calib->GetNextRow();
+    for (int i =0 ; i<size_of_offset; i++)
+    {
+        offset[i] = short(offset_mV[i] / 2000. * 4096 - 0.5);
+    }
+    cout << endl;
+    delete[] offset_mV;
+    delete calib;
+    calib = NULL;
+    //=========================================================================
+    // END OF                CALIBRATION CONSTANTS
+    //=========================================================================
+    
+    
+    ifstream datafile (data_file_name, ios::in|ios::binary);
+    ofstream out (out_file_name, ios::out|ios::binary|ios::trunc);
+    if (datafile.is_open() && out.is_open())
+    {
+        // copy first 0x2d00 bytes to new file
+        const int ascii_header_size = 0x2d00;
+        char * memblock = new char [ascii_header_size];
+        datafile.read(memblock, ascii_header_size);
+        out.write(memblock, ascii_header_size);
+        delete[] memblock;
+        
+        for ( int event_id = 0 ; event_id < 1000; event_id++)
+        //while ( datafile.good() )
+        {
+            // copy binary header to new file
+            const int bin_header_size = 3390;
+            char * memblock = new char [bin_header_size];
+            datafile.read(memblock, bin_header_size);
+            out.write(memblock, bin_header_size);
+            delete[] memblock;
+           
+            // read the size of the compressed next event
+            int cs;
+            datafile.read((char*)&cs, sizeof(cs));
+            const int data_size = cs;
+
+            // read cs bytes out of the file
+            for (int chid = 0 ; chid < 1440; chid++)
+            {
+                int slices =0;
+                short first_short;
+                datafile.read((char*)&first_short, sizeof(first_short));
+                out.write( (char*)&first_short, sizeof(first_short) );
+
+                while (slices < 300)
+                {
+                    // read header
+                    short header;
+                    short group_size;
+                    int is_short;
+                    datafile.read((char*)&header, sizeof(header));
+                    if (header & 0x8000)
+                    {
+                        // the group data consists of shorts
+                        group_size = header | 0x7FFF;
+                        short *group;
+                        group = new short [group_size];
+                        datafile.read( (char*)group, group_size*sizeof(short) );
+                        for (int groupsl = 0; groupsl < group_size; groupsl++)
+                        {
+                            first_short += group[groupsl];
+                            out.write( (char*)&first_short, sizeof(short) );
+                        }
+                        delete[] group;
+                    }
+                    else
+                    {
+                        // the group data consists of bytes
+                        group_size = header;
+                        char *group;
+                        group = new char [group_size];
+                        datafile.read( (char*)group, group_size*sizeof(char) );
+                        for (int groupsl = 0; groupsl < group_size; groupsl++)
+                        {
+                            first_short += group[groupsl];
+                            out.write( (char*)&first_short, sizeof(short) );
+                        }
+                        delete[] group;
+                    }
+
+                    slices += group_size;
+
+                }
+            }
+        
+        
+        datafile.close();
+        out.close();
+  } //end of if file open
+} //end of main
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/factcompress.cpp
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/factcompress.cpp	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/factcompress.cpp	(revision 14268)
@@ -0,0 +1,259 @@
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string.h>
+
+// I will use the fits class by TB for reading the interesting data from the files
+
+#include "izstream.h"
+
+#define HAVE_ZLIB
+#include "fits.h"
+
+using namespace std;
+
+ifstream::pos_type size;
+char * memblock;
+
+int main (int argc, char * argv[]) {
+
+
+    if (argc < 3)
+    {
+        cout << "Usage: " << argv[0] << " data-file-name calib-file-name [ouput-file-name]" << endl;
+        cout << "" << endl;
+    }
+    
+    char * data_file_name = argv[1];
+    char * calib_file_name = argv[2];
+    char * out_file_name = 0;
+    if (argc == 4)
+    {
+        out_file_name = argv[3];
+    }
+    else
+    {
+        out_file_name = new char[strlen(data_file_name)+4];
+        strcpy(out_file_name, data_file_name);
+        strcpy(out_file_name+strlen(data_file_name),".fc");
+        out_file_name[strlen(data_file_name)+3] = 0;
+    }
+    
+    
+    
+    
+    //=========================================================================
+    // CALIBRATION CONSTANTS
+    //=========================================================================
+    fits * calib =new fits(calib_file_name);
+    calib->PrintKeys();
+    calib->PrintColumns();
+
+    int size_of_offset = 1440*1024;
+    float * offset_mV = new float[size_of_offset];
+    short * offset = new short[size_of_offset];
+    calib->SetPtrAddress("BaselineMean",offset_mV, size_of_offset);
+
+    calib->GetNextRow();
+    for (int i =0 ; i<size_of_offset; i++)
+    {
+        offset[i] = short(offset_mV[i] / 2000. * 4096 - 0.5);
+    }
+    cout << endl;
+    delete[] offset_mV;
+    delete calib;
+    calib = NULL;
+    //=========================================================================
+    // END OF                CALIBRATION CONSTANTS
+    //=========================================================================
+    
+    
+    ifstream datafile (data_file_name, ios::in|ios::binary);
+    ofstream out (out_file_name, ios::out|ios::binary|ios::trunc);
+    if (datafile.is_open() && out.is_open())
+    {
+        // create our own header
+        //out.write( "FACT_COMPRESS                                                                   ", 80);
+        //out.write( "END.                                                                            ", 80);
+        
+        // copy first 0x2d00 bytes to new file
+        const int ascii_header_size = 0x2d00;
+        char * memblock = new char [ascii_header_size];
+        datafile.read(memblock, ascii_header_size);
+        out.write(memblock, ascii_header_size);
+        delete[] memblock;
+        
+        for ( int event_id = 0 ; event_id < 1000; event_id++)
+        //while ( datafile.good() )
+        {
+            // copy binary header to new file
+            const int bin_header_size = 3390;
+            char * memblock = new char [bin_header_size];
+            datafile.read(memblock, bin_header_size);
+            out.write(memblock, bin_header_size);
+            delete[] memblock;
+           
+            cout << "aaaaaaaaaaaaaaaa" << hex << datafile.tellg() << endl;
+
+            // read 300 shorts out of the file
+            for (int chid = 0 ; chid < 1440; chid++)
+            {
+                const int data_size = 300;
+                const int diff_size = data_size;
+                char * memblock = new char [data_size*sizeof(short)];
+                short * data = (short *)memblock;
+                short * diffs = new short [diff_size];
+                unsigned char * sizes = new unsigned char [diff_size];
+                
+                datafile.read(memblock, data_size*sizeof(short) );
+                
+                for ( int i = 0; i<diff_size; i++)
+                {
+                    diffs[i] = data[i]-data[i];
+                    //~ if (diffs[i] >= -32 && diffs[i] <= 31)
+                        //~ sizes[i] = 6;
+                    //~ else if (diffs[i] >= -128 && diffs[i] <= 127)
+                        //~ sizes[i] = 8;
+                    //~ else if (diffs[i] >= -512 && diffs[i] <= 511)
+                        //~ sizes[i] = 10;
+                    //~ else
+                        //~ sizes[i] = 16;
+                    if (diffs[i] >= -128 && diffs[i] <= 127)
+                        sizes[i] = 8;
+                    else
+                        sizes[i] = 16;
+                }
+                
+                // calculate group sizes
+                int counter = 0;
+                unsigned char last_size = sizes[0];
+                vector<int> group_sizes;
+                vector<unsigned char> groups;
+                
+                for (int i=0 ; i < diff_size; i++)
+                {
+                    
+                    if (sizes[i] != last_size)
+                    {
+                        group_sizes.push_back( counter );
+                        groups.push_back( last_size );
+                        last_size = sizes[i];
+                    }
+                    counter++;
+                }
+                groups.push_back( last_size );
+                group_sizes.push_back( counter );
+                
+
+                // measure how large the stuff, is
+                int cs =0;
+                // for all groups write header and group
+                short header = 0;
+                int diff_index = 0;
+                for ( int i = 0 ; i < (int)groups.size() ; i++)
+                {
+                    // write header
+                    if (groups[i] == 8)
+                    {
+                        header = short(group_sizes[i]);
+                    }
+                    else
+                    {
+                        header = 0x8000 | short(group_sizes[i] );
+                    }
+                    cs += sizeof(short);
+
+                    // write group
+                    if (groups[i] == 8)
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            cs += 1;
+                        }
+                    }
+                    else
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            cs += 2;
+                        }
+                    }
+                }
+                //cout << "compressed size:" << cs << endl;
+                out.write( (char*)&cs, sizeof(cs));
+
+                cout << "sizeof(cs):" << sizeof(cs) << endl;
+
+                // write the first short
+                out.write(memblock, 1*sizeof(short) );
+                printf("first short: 0x%X \t %d \n", ( (short*)memblock )[0], ( (short*)memblock )[0] );
+                // for all groups write header and group
+                header = 0;
+                diff_index = 0;
+                for ( int i = 0 ; i < (int)groups.size() ; i++)
+                {
+                    // write header
+                    if (groups[i] == 8)
+                    {
+                        header = short(group_sizes[i]);
+                    }
+                    else
+                    {
+                        header = 0x8000 | short(group_sizes[i] );
+                    }
+                    out.write( (char*)&header, sizeof(short));
+                    
+                    // write group
+                    if (groups[i] == 8)
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            out.write( (char*)&(diffs[diff_index++]), 1);
+                        }
+                    }
+                    else
+                    {
+                        for (int j = 0; j<group_sizes[i]; j++)
+                        {
+                            out.write( (char*)&(diffs[diff_index++]), 2);
+                        }
+                    }
+                }
+                
+                //out.write(memblock, data_size*sizeof(short) );
+                
+                delete[] memblock;
+                delete[] diffs;
+                delete[] sizes;
+            }
+        }
+        cout << "finished with 1000 events." << endl;
+        long after_address = datafile.tellg();
+        datafile.seekg (0, ios::end);
+        long end = datafile.tellg();
+        datafile.seekg (after_address, ios::beg);
+        
+        cout << "between last event and end:" << end - after_address << endl;
+        // read the last piece...
+        const int rest_size = end-after_address;
+        char * memblock2 = new char [rest_size];
+        datafile.read(memblock2, rest_size);
+        cout << "first char in memblock: " << int(memblock2[0]) << endl;
+        char lastchar = memblock2[0];
+        for (int i =0 ; i<rest_size; i++)
+        {
+            if (memblock2[i] != lastchar)
+            {
+                cout << "new char at: " << i << " with value:" << int(memblock[0]) << endl;
+                lastchar = memblock2[i];
+            }
+        }
+        
+        out.write(memblock2, rest_size);
+        delete[] memblock2;
+        
+        
+        datafile.close();
+        out.close();
+  } //end of if file open
+} //end of main
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/fits.h
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/fits.h	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/fits.h	(revision 14268)
@@ -0,0 +1,718 @@
+#ifndef MARS_fits
+#define MARS_fits
+
+#include <stdint.h>
+
+#include <map>
+#include <string>
+#include <sstream>
+#include <algorithm>
+
+#ifdef __EXCEPTIONS
+#include <stdexcept>
+#endif
+
+#ifdef __CINT__
+#define off_t size_t
+#endif
+
+#ifndef __MARS__
+#include <vector>
+#include <iomanip>
+#include <iostream>
+#define gLog cerr
+#define ___err___ ""
+#define ___all___ ""
+#else
+#include "MLog.h"
+#include "MLogManip.h"
+#define ___err___ err
+#define ___all___ all
+#endif
+
+#ifdef HAVE_ZLIB
+#include "izstream.h"
+#else
+#include <fstream>
+#define izstream ifstream
+//#warning Support for zipped FITS files disabled.
+#endif
+
+
+namespace std
+{
+
+class fits : public izstream
+{
+public:
+    struct Entry
+    {
+        char   type;
+        string value;
+        string comment;
+
+        template<typename T>
+            T Get() const
+        {
+            T t;
+
+            istringstream str(value);
+            str >> t;
+
+            return t;
+        }
+    };
+
+    struct Table
+    {
+        off_t offset;
+
+        string name;
+        size_t bytes_per_row;
+        size_t num_rows;
+        size_t num_cols;
+
+        struct Column
+        {
+            size_t offset;
+            size_t num;
+            size_t size;
+            char   type;
+            string unit;
+        };
+
+        typedef map<string, Entry>  Keys;
+        typedef map<string, Column> Columns;
+
+        Columns cols;
+        Keys    keys;
+
+        string Trim(const string &str, char c=' ') const
+        {
+            // Trim Both leading and trailing spaces
+            const size_t pstart = str.find_first_not_of(c); // Find the first character position after excluding leading blank spaces
+            const size_t pend   = str.find_last_not_of(c);  // Find the first character position from reverse af
+
+            // if all spaces or empty return an empty string
+            if (string::npos==pstart || string::npos==pend)
+                return string();
+
+            return str.substr(pstart, pend-pstart+1);
+        }
+
+        bool Check(const string &key, char type, const string &value="") const
+        {
+            const Keys::const_iterator it = keys.find(key);
+            if (it==keys.end())
+            {
+                ostringstream str;
+                str << "Key '" << key << "' not found.";
+#ifdef __EXCEPTIONS
+                throw runtime_error(str.str());
+#else
+                gLog << ___err___ << "ERROR - " << str.str() << endl;
+                return false;
+#endif
+            }
+
+            if (it->second.type!=type)
+            {
+                ostringstream str;
+                str << "Wrong type for key '" << key << "': expected " << type << ", found " << it->second.type << ".";
+#ifdef __EXCEPTIONS
+                throw runtime_error(str.str());
+#else
+                gLog << ___err___ << "ERROR - " << str.str() << endl;
+                return false;
+#endif
+            }
+
+            if (!value.empty() && it->second.value!=value)
+            {
+                ostringstream str;
+                str << "Wrong value for key '" << key << "': expected " << value << ", found " << it->second.value << ".";
+#ifdef __EXCEPTIONS
+                throw runtime_error(str.str());
+#else
+                gLog << ___err___ << "ERROR - " << str.str() << endl;
+                return false;
+#endif
+            }
+
+            return true;
+        }
+
+        Keys ParseBlock(const vector<string> &vec) const
+        {
+            map<string,Entry> rc;
+
+            for (unsigned int i=0; i<vec.size(); i++)
+            {
+                const string key = Trim(vec[i].substr(0,8));
+                // Keywords without a value, like COMMENT / HISTORY
+                if (vec[i].substr(8,2)!="= ")
+                    continue;
+
+                char type = 0;
+
+                string com;
+                string val = Trim(vec[i].substr(10));
+                if (val[0]=='\'')
+                {
+                    // First skip all '' in the string
+                    size_t p = 1;
+                    while (1)
+                    {
+                        const size_t pp = val.find_first_of('\'', p);
+                        if (pp==string::npos)
+                            break;
+
+                        p = val[pp+1]=='\'' ? pp+2 : pp+1;
+                    }
+
+                    // Now find the comment
+                    const size_t ppp = val.find_first_of('/', p);
+
+                    // Set value, comment and type
+                    com  = ppp==string::npos ? "" : Trim(val.substr(ppp+1));
+                    val  = Trim(val.substr(1, p-2));
+                    type = 'T';
+                }
+                else
+                {
+                    const size_t p = val.find_first_of('/');
+
+                    com = Trim(val.substr(p+2));
+                    val = Trim(val.substr(0, p));
+
+                    if (val.empty() || val.find_first_of('T')!=string::npos || val.find_first_of('F')!=string::npos)
+                        type = 'B';
+                    else
+                        type = val.find_last_of('.')==string::npos ? 'I' : 'F';
+                }
+
+                const Entry e = { type, val, com };
+                rc[key] = e;
+            }
+
+            return rc;
+        }
+
+        Table() : offset(0) { }
+        Table(const vector<string> &vec, off_t off) :
+            offset(off), keys(ParseBlock(vec))
+        {
+            if (!Check("XTENSION", 'T', "BINTABLE") ||
+                !Check("NAXIS",    'I', "2")        ||
+                !Check("BITPIX",   'I', "8")        ||
+                !Check("PCOUNT",   'I', "0")        ||
+                !Check("GCOUNT",   'I', "1")        ||
+                !Check("EXTNAME",  'T')             ||
+                !Check("NAXIS1",   'I')             ||
+                !Check("NAXIS2",   'I')             ||
+                !Check("TFIELDS",  'I'))
+                return;
+
+            bytes_per_row = Get<size_t>("NAXIS1");
+            num_rows      = Get<size_t>("NAXIS2");
+            num_cols      = Get<size_t>("TFIELDS");
+
+            size_t bytes = 0;
+            for (size_t i=1; i<=num_cols; i++)
+            {
+                ostringstream num;
+                num << i;
+
+                if (!Check("TTYPE"+num.str(), 'T') ||
+                    !Check("TFORM"+num.str(), 'T'))
+                    return;
+
+                const string id   = Get<string>("TTYPE"+num.str());
+                const string fmt  = Get<string>("TFORM"+num.str());
+                const string unit = Get<string>("TUNIT"+num.str(), "");
+
+                istringstream sin(fmt);
+                int n = 0;
+                sin >> n;
+                if (!sin)
+                    n = 1;
+
+                const char type = fmt[fmt.length()-1];
+
+                size_t size = 0;
+                switch (type)
+                {
+                    // We could use negative values to mark floats
+                    // otheriwse we could just cast them to int64_t?
+                case 'L': size = 1; break; // logical
+                // case 'X': size = n; break; // bits (n=number of bytes needed to contain all bits)
+                case 'B': size = 1; break; // byte
+                case 'I': size = 2; break; // short
+                case 'J': size = 4; break; // int
+                case 'K': size = 8; break; // long long
+                case 'E': size = 4; break; // float
+                case 'D': size = 8; break; // double
+                // case 'C': size =  8; break; // complex float
+                // case 'M': size = 16; break; // complex double
+                // case 'P': size =  8; break; // array descriptor (32bit)
+                // case 'Q': size = 16; break; // array descriptor (64bit)
+                default:
+                    {
+                        ostringstream str;
+                        str << "FITS format TFORM='" << fmt << "' not yet supported.";
+#ifdef __EXCEPTIONS
+                        throw runtime_error(str.str());
+#else
+                        gLog << ___err___ << "ERROR - " << str.str() << endl;
+                        return;
+#endif
+                    }
+                }
+
+                const Table::Column col = { bytes, n, size, type, unit };
+
+                cols[id] = col;
+                bytes  += n*size;
+            }
+
+            if (bytes!=bytes_per_row)
+            {
+#ifdef __EXCEPTIONS
+                throw runtime_error("Column size mismatch");
+#else
+                gLog << ___err___ << "ERROR - Column size mismatch" << endl;
+                return;
+#endif
+            }
+
+            name = Get<string>("EXTNAME");
+        }
+
+        void PrintKeys(bool display_all=false) const
+        {
+            for (Keys::const_iterator it=keys.begin(); it!=keys.end(); it++)
+            {
+                if (!display_all &&
+                    (it->first.substr(0, 6)=="TTYPE" ||
+                     it->first.substr(0, 6)=="TFORM" ||
+                     it->first.substr(0, 6)=="TUNIT" ||
+                     it->first=="TFIELDS"  ||
+                     it->first=="XTENSION" ||
+                     it->first=="NAXIS"    ||
+                     it->first=="BITPIX"   ||
+                     it->first=="PCOUNT"   ||
+                     it->first=="GCOUNT")
+                   )
+                    continue;
+
+                gLog << ___all___ << setw(2) << it->second.type << '|' << it->first << '=' << it->second.value << '/' << it->second.comment << '|' << endl;
+            }}
+
+        void PrintColumns() const
+        {
+            typedef map<pair<size_t, string>, Column> Sorted;
+
+            Sorted sorted;
+
+            for (Columns::const_iterator it=cols.begin(); it!=cols.end(); it++)
+                sorted[make_pair(it->second.offset, it->first)] = it->second;
+
+            for (Sorted::const_iterator it=sorted.begin(); it!=sorted.end(); it++)
+            {
+                gLog << ___all___ << setw(6) << it->second.offset << "| ";
+                gLog << it->second.num << 'x';
+                switch (it->second.type)
+                {
+                case 'L': gLog << "bool(8)";    break;
+                case 'B': gLog << "byte(8)";    break;
+                case 'I': gLog << "short(16)";  break;
+                case 'J': gLog << "int(32)";    break;
+                case 'K': gLog << "int(64)";    break;
+                case 'E': gLog << "float(32)";  break;
+                case 'D': gLog << "double(64)"; break;
+                }
+                gLog << ": " << it->first.second << " [" << it->second.unit << "]" << endl;
+            }
+        }
+
+        operator bool() const { return !name.empty(); }
+
+        bool HasKey(const string &key) const
+        {
+            return keys.find(key)!=keys.end();
+        }
+
+            // Values of keys are always signed
+        template<typename T>
+            T Get(const string &key) const
+        {
+            const map<string,Entry>::const_iterator it = keys.find(key);
+            if (it==keys.end())
+            {
+                ostringstream str;
+                str << "Key '" << key << "' not found." << endl;
+#ifdef __EXCEPTIONS
+                throw runtime_error(str.str());
+#else
+                gLog << ___err___ << "ERROR - " << str.str() << endl;
+                return 0;
+#endif
+            }
+            return it->second.Get<T>();
+        }
+
+            // Values of keys are always signed
+        template<typename T>
+            T Get(const string &key, const string &deflt) const
+        {
+            const map<string,Entry>::const_iterator it = keys.find(key);
+            return it==keys.end() ? deflt :it->second.Get<T>();
+        }
+
+        size_t GetN(const string &key) const
+        {
+            const Columns::const_iterator it = cols.find(key);
+            if (it==cols.end()){
+                ostringstream str;
+                str << "Key '" << key << "' not found." << endl;
+                str << "Possible keys are:" << endl;
+                for ( Columns::const_iterator it=cols.begin() ; it != cols.end(); ++it){
+                    str << it->first << endl;
+                }
+#ifdef __EXCEPTIONS
+                throw runtime_error(str.str());
+#else
+                gLog << ___err___ << "ERROR - " << str.str() << endl;
+                return 0;
+#endif
+            }
+            return it==cols.end() ? 0 : it->second.num;
+        }
+    };
+
+private:
+    Table fTable;
+
+    typedef pair<void*, Table::Column> Address;
+    typedef vector<Address> Addresses;
+    //map<void*, Table::Column> fAddresses;
+    Addresses fAddresses;
+
+    vector<char> fBufferRow;
+    vector<char> fBufferDat;
+
+    size_t fRow;
+
+    vector<string> ReadBlock(vector<string> &vec)
+    {
+        bool endtag = false;
+        for (int i=0; i<36; i++)
+        {
+            char c[81];
+            c[80] = 0;
+            read(c, 80);
+            if (!good())
+                break;
+
+            if (c[0]==0)
+                return vector<string>();
+
+            string str(c);
+
+//            if (!str.empty())
+//                cout << setw(2) << i << "|" << str << "|" << (endtag?'-':'+') << endl;
+
+            if (str=="END                                                                             ")
+            {
+                endtag = true;
+
+                // Make sure that no empty vector is returned
+                if (vec.size()%36==0)
+                    vec.push_back(string("END     = '' / "));
+            }
+
+            if (endtag)
+                continue;
+
+            vec.push_back(str);
+        }
+
+        return vec;
+    }
+
+    string Compile(const string &key, int16_t i=-1)
+    {
+        if (i<0)
+            return key;
+
+        ostringstream str;
+        str << key << i;
+        return str.str();
+    }
+
+public:
+    fits(const string &fname) : izstream(fname.c_str())
+    {
+        char simple[10];
+        read(simple, 10);
+        if (!good())
+            return;
+
+        if (memcmp(simple, "SIMPLE  = ", 10))
+        {
+            clear(rdstate()|ios::badbit);
+#ifdef __EXCEPTIONS
+            throw runtime_error("File is not a FITS file.");
+#else
+            gLog << ___err___ << "ERROR - File is not a FITS file." << endl;
+            return;
+#endif
+        }
+
+        seekg(0);
+
+        while (good())
+        {
+            vector<string> block;
+            while (1)
+            {
+                // FIXME: Set limit on memory consumption
+                ReadBlock(block);
+                if (!good())
+                {
+                    clear(rdstate()|ios::badbit);
+#ifdef __EXCEPTIONS
+                    throw runtime_error("FITS file corrupted.");
+#else
+                    gLog << ___err___ << "ERROR - FITS file corrupted." << endl;
+                    return;
+#endif
+                }
+
+                if (block.size()%36)
+                    break;
+            }
+
+            if (block.size()==0)
+                break;
+
+            if (block[0].substr(0, 9)=="SIMPLE  =")
+                continue;
+
+            if (block[0].substr(0, 9)=="XTENSION=")
+            {
+                // FIXME: Check for table name
+
+                fTable = Table(block, tellg());
+                fRow   = (size_t)-1;
+
+                //fTable.PrintKeys();
+
+                if (!fTable)
+                {
+                    clear(rdstate()|ios::badbit);
+                    return;
+                }
+
+                fBufferRow.resize(fTable.bytes_per_row);
+                fBufferDat.resize(fTable.bytes_per_row);
+
+                /*
+                 // Next table should start at:
+                 const size_t size = fTable.bytes_per_row*fTable.num_rows;
+                 const size_t blks = size/(36*80);
+                 const size_t rest = size%(36*80);
+
+                seekg((blks+(rest>0?1:0))*(36*80), ios::cur);
+                if (!good())
+                     gLog << ___err___ << "File seems to be incomplete (less data than expected from header)." << endl;
+
+                fRow   = fTable.num_rows;
+                 */
+
+                break;
+            }
+        }
+    }
+
+    void ReadRow(size_t row)
+    {
+        // if (row!=fRow+1) // Fast seeking is ensured by izstream
+        seekg(fTable.offset+row*fTable.bytes_per_row);
+
+        fRow = row;
+
+        read(fBufferRow.data(), fBufferRow.size());
+        //fin.clear(fin.rdstate()&~ios::eofbit);
+    }
+
+    template<size_t N>
+        void revcpy(char *dest, const char *src, int num)
+    {
+        const char *pend = src + num*N;
+        for (const char *ptr = src; ptr<pend; ptr+=N, dest+=N)
+            reverse_copy(ptr, ptr+N, dest);
+    }
+
+    bool GetRow(size_t row)
+    {
+        ReadRow(row);
+        if (!good())
+            return good();
+
+        for (Addresses::const_iterator it=fAddresses.begin(); it!=fAddresses.end(); it++)
+        {
+            const Table::Column &c = it->second;
+
+            const char *src = fBufferRow.data() + c.offset;
+            char *dest = reinterpret_cast<char*>(it->first);
+
+            // Let the compiler do some optimization by
+            // knowing the we only have 1, 2, 4 and 8
+            switch (c.size)
+            {
+            case 1: memcpy   (dest, src, c.num*c.size); break;
+            case 2: revcpy<2>(dest, src, c.num);        break;
+            case 4: revcpy<4>(dest, src, c.num);        break;
+            case 8: revcpy<8>(dest, src, c.num);        break;
+            }
+        }
+
+        return good();
+    }
+
+    bool GetNextRow()
+    {
+        return GetRow(fRow+1);
+    }
+
+    bool SkipNextRow()
+    {
+        seekg(fTable.offset+(++fRow)*fTable.bytes_per_row);
+        return good();
+    }
+
+    static bool Compare(const Address &p1, const Address &p2)
+    {
+        return p1.first>p2.first;
+    }
+
+    template<typename T>
+    bool SetPtrAddress(const string &name, T *ptr, size_t cnt)
+    {
+        if (fTable.cols.count(name)==0)
+        {
+            ostringstream str;
+            str <<"SetPtrAddress('" << name << "') - Column not found." << endl;
+#ifdef __EXCEPTIONS
+            throw runtime_error(str.str());
+#else
+            gLog << ___err___ << "ERROR - " << str.str() << endl;
+            return false;
+#endif
+        }
+
+        if (sizeof(T)!=fTable.cols[name].size)
+        {
+            ostringstream str;
+            str << "SetPtrAddress('" << name << "') - Element size mismatch: expected "
+                << fTable.cols[name].size << " from header, got " << sizeof(T) << endl;
+#ifdef __EXCEPTIONS
+            throw runtime_error(str.str());
+#else
+            gLog << ___err___ << "ERROR - " << str.str() << endl;
+            return false;
+#endif
+        }
+
+        if (cnt!=fTable.cols[name].num)
+        {
+            ostringstream str;
+            str << "SetPtrAddress('" << name << "') - Element count mismatch: expected "
+                << fTable.cols[name].num << " from header, got " << cnt << endl;
+#ifdef __EXCEPTIONS
+            throw runtime_error(str.str());
+#else
+            gLog << ___err___ << "ERROR - " << str.str() << endl;
+            return false;
+#endif
+        }
+
+        // if (fAddresses.count(ptr)>0)
+        //     gLog << warn << "SetPtrAddress('" << name << "') - Pointer " << ptr << " already assigned." << endl;
+
+        //fAddresses[ptr] = fTable.cols[name];
+        fAddresses.push_back(make_pair(ptr, fTable.cols[name]));
+        sort(fAddresses.begin(), fAddresses.end(), Compare);
+        return true;
+    }
+
+    template<class T>
+    bool SetRefAddress(const string &name, T &ptr)
+    {
+        return SetPtrAddress(name, &ptr, sizeof(ptr)/sizeof(T));
+    }
+
+    template<typename T>
+    bool SetVecAddress(const string &name, vector<T> &vec)
+    {
+        return SetPtrAddress(name, vec.data(), vec.size());
+    }
+
+    template<typename T>
+        T Get(const string &key) const
+    {
+        return fTable.Get<T>(key);
+    }
+
+    template<typename T>
+        T Get(const string &key, const string &deflt) const
+    {
+        return fTable.Get<T>(key, deflt);
+    }
+
+    bool SetPtrAddress(const string &name, void *ptr)
+    {
+        if (fTable.cols.count(name)==0)
+        {
+            ostringstream str;
+            str <<"SetPtrAddress('" << name << "') - Column not found." << endl;
+#ifdef __EXCEPTIONS
+            throw runtime_error(str.str());
+#else
+            gLog << ___err___ << "ERROR - " << str.str() << endl;
+            return false;
+#endif
+        }
+
+        // if (fAddresses.count(ptr)>0)
+        //     gLog << warn << "SetPtrAddress('" << name << "') - Pointer " << ptr << " already assigned." << endl;
+
+        //fAddresses[ptr] = fTable.cols[name];
+        fAddresses.push_back(make_pair(ptr, fTable.cols[name]));
+        sort(fAddresses.begin(), fAddresses.end(), Compare);
+        return true;
+    }
+
+    bool     HasKey(const string &key) const { return fTable.HasKey(key); }
+    int64_t  GetInt(const string &key) const { return fTable.Get<int64_t>(key); }
+    uint64_t GetUInt(const string &key) const { return fTable.Get<uint64_t>(key); }
+    double   GetFloat(const string &key) const { return fTable.Get<double>(key); }
+    string   GetStr(const string &key) const { return fTable.Get<string>(key); }
+
+    size_t GetN(const string &key) const
+    {
+        return fTable.GetN(key);
+    }
+
+    size_t GetNumRows() const { return fTable.num_rows; }
+    size_t GetRow() const { return fRow; }
+
+    operator bool() const { return fTable && fTable.offset!=0; }
+
+    void PrintKeys() const { fTable.PrintKeys(); }
+    void PrintColumns() const { fTable.PrintColumns(); }
+};
+
+};
+#endif
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/helper.cpp
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/helper.cpp	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/helper.cpp	(revision 14268)
@@ -0,0 +1,32 @@
+#include <fstream>
+#include "helper.hxx"
+
+using namespace std;
+
+helper::helper( std::ifstream * in, std::ofstream * out)
+{
+    infile = in;
+    outfile = out;
+}
+
+void helper::copy_ascii_header()
+{
+    // copy first 0x2d00 bytes to new file
+    const int ascii_header_size = 0x2d00;
+    char * memblock = new char [ascii_header_size];
+    infile->seekg(0, ios::beg);
+    infile->read(memblock, ascii_header_size);
+    outfile->write(memblock, ascii_header_size);
+    delete[] memblock;
+}
+
+void helper::copy_event_header()
+{
+    // copy binary header to new file
+   const int bin_header_size = 3390;
+   char * memblock = new char [bin_header_size];
+   event_header_start = infile->tellg();
+   infile->read(memblock, bin_header_size);
+   outfile->write(memblock, bin_header_size);
+   delete[] memblock;
+}
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/izstream.h
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/izstream.h	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/izstream.h	(revision 14268)
@@ -0,0 +1,176 @@
+#ifndef MARS_izstream
+#define MARS_izstream
+
+#include <istream>
+#include <streambuf>
+
+#ifdef __MARS__
+#ifndef ROOT_TObject
+#include <TObject.h> // Needed for ClassDef
+#endif
+#endif
+
+#ifdef __CINT__
+typedef void *gzFile;
+#else
+#include <zlib.h>
+#endif
+
+class izstream : public std::streambuf, public std::istream
+{
+private:
+    static const int fgBufferSize = 3276804; // maximum size of a fact event + 4
+
+    gzFile fFile;                 // file handle for compressed file
+    char   fBuffer[fgBufferSize]; // data buffer
+
+    int underflow()
+    {
+        if (gptr() && gptr()<egptr())
+            return * reinterpret_cast<unsigned char *>(gptr());
+
+        if (!is_open())
+            return EOF;
+
+        // gptr()-eback(): if more than four bytes are already flushed
+        const int iputback = gptr()-eback()>4 ? 4 : gptr()-eback();
+
+        // Copy the last four bytes flushed into the putback area
+        memcpy(fBuffer+(4-iputback), gptr()-iputback, iputback);
+
+        // Fill the buffer starting at the current file position and reset buffer
+        // pointers by calling setg
+        const int num = gzread(fFile, fBuffer+4, fgBufferSize-4);
+        if (num <= 0) // ERROR or EOF
+            return EOF;
+
+        // reset buffer pointers
+        setg(fBuffer+(4-iputback), fBuffer+4, fBuffer+4+num);
+
+        // return next character
+        return *reinterpret_cast<unsigned char *>(gptr());
+    }
+
+
+public:
+    izstream() : std::istream(this), fFile(0)
+    {
+        setg(fBuffer+4, fBuffer+4, fBuffer+4);
+    }
+    izstream(const char *name) : std::istream(this), fFile(0)
+    {
+        setg(fBuffer+4, fBuffer+4, fBuffer+4);
+        open(name);
+    }
+    ~izstream() { izstream::close(); }
+
+    int is_open() { return fFile!=0; }
+
+    // --------------------------------------------------------------------------
+    //
+    // Open a file by name. Test if it is open like for an ifstream
+    // It doesn't matter whether the file is gzip compressed or not.
+    //
+    void open(const char* name)
+    {
+        if (is_open())
+        {
+            clear(rdstate()|std::ios::failbit);
+            return;
+        }
+
+        fFile = gzopen(name, "rb");
+        if (fFile == 0)
+        {
+            clear(rdstate()|std::ios::failbit);
+            return;
+        }
+    }
+    // --------------------------------------------------------------------------
+    //
+    // Close an open file.
+    //
+    void close()
+    {
+        if (!is_open())
+            return;
+
+        if (gzclose(fFile) != Z_OK)
+            clear(rdstate()|std::ios::failbit);
+
+        fFile = 0;
+    }
+
+    std::streambuf::pos_type seekoff(std::streambuf::off_type offset, std::ios_base::seekdir dir,
+                                     std::ios_base::openmode = std::ios_base::in)
+    {
+        // Using a switch instead results in:
+        //  In member function `virtual std::streampos izstream::seekoff(long int, std::_Ios_Seekdir, std::_Ios_Openmode)':
+        //  warning: enumeration value `_M_ios_seekdir_end' not handled in switch
+        //  warning: case value `0' not in enumerated type `_Ios_Seekdir'
+        //  warning: case value `1' not in enumerated type `_Ios_Seekdir'
+        //  warning: case value `2' not in enumerated type `_Ios_Seekdir'
+
+        if (dir==std::ios::end)
+        {
+            clear(rdstate()|std::ios::failbit);
+            return EOF;
+        }
+
+        // We only do relative seeking to avoid unnecessary decompression
+        // of the whole file
+        if (dir==std::ios::beg)
+            offset -= tellg();
+
+        // Calculate future position in streambuffer
+        const char *ptr = gptr()+offset;
+
+        // This is the number of bytes still available in the buffer
+        const size_t sbuf = egptr()-gptr();
+
+        // Check if the new position will still be in the buffer
+        // In this case the target data was already decompressed.
+        if (ptr>=eback() && ptr<egptr())
+        {
+            // Absolute position in z-stream
+            const z_off_t zpos = gztell(fFile)-sbuf; //gzseek(fFile, 0, SEEK_CUR);
+
+            gbump(offset);
+
+            return zpos+offset;
+        }
+
+        const streampos pos = gzseek(fFile, offset-sbuf, SEEK_CUR);
+
+        // Buffer is empty - force refilling
+        setg(fBuffer+4, fBuffer+4, fBuffer+4);
+
+        return pos<0 ? streampos(EOF) : pos;
+
+        /*
+         // SEEK_END not supported by zlib
+         if (dir==ios::end)
+         {
+             // Position in z-stream
+             const z_off_t zpos = gzseek(fFile, offset, SEEK_END);
+             if (zpos<0)
+                 return EOF;
+
+             return fill_buffer()==EOF ? EOF : zpos;
+         }
+         */
+        return EOF;
+    }
+
+    std::streambuf::pos_type seekpos(std::streambuf::pos_type pos,
+                                     std::ios_base::openmode = std::ios_base::in)
+    {
+        return seekoff(pos, std::ios::beg);
+    }
+
+#ifdef __MARS__
+    ClassDef(izstream, 0) // A C++ wrapper to istream zlib files
+#endif
+};
+
+#endif
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/readfits.cpp
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/readfits.cpp	(revision 14267)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/readfits.cpp	(revision 14268)
@@ -1,11 +1,13 @@
-
-// reading a complete binary file
 #include <iostream>
 #include <fstream>
 #include <vector>
+#include <string.h>
 
 // I will use the fits class by TB for reading the interesting data from the files
+
+#include "izstream.h"
+
 #define HAVE_ZLIB
-#include "fits"
+#include "fits.h"
 
 using namespace std;
@@ -15,5 +17,6 @@
 
 int main (int argc, char * argv[]) {
-    
+
+
     if (argc < 3)
     {
@@ -45,44 +48,20 @@
     fits * calib =new fits(calib_file_name);
     calib->PrintKeys();
-    calib->PrintColums();
-    offset_mV = new float[]
-    
-    // I need the offset calibration constants from the calibration files
-    // they are stored as floats at a known position inside the calibration file...
-    long position_of_calibration_constants = 0x1000;
-    // The calibration constants are stored in units of pseudo-mV. 
-    // but I need them in ADC units
-    // I will first read offset_mV from the file, then multiply (or divide) 
-    // with the conversion factor 2000/4096.;
-    // then I will convert it to shorts.
-    // From that point on I will only use the shorts in *offset*, so I can
-    // free the memory for *offset_mV* already.
+    calib->PrintColumns();
+
     int size_of_offset = 1440*1024;
-    int size_of_offset_memblock = 1440*1024*sizeof(float);
     float * offset_mV = new float[size_of_offset];
     short * offset = new short[size_of_offset];
-    char * memblock = new char[size_of_offset_memblock];
-    
-    ifstream calib (calib_file_name, ios::in|ios::binary);
-    if ( !calib.is_open() )
-    {
-        cerr << "Could not open Calibration File:" << calib_file_name << ".. ABORT." << endl;
-        return 1;
-    }
-    else // file was opened, I can go on...
-    {
-        calib.seekg(position_of_calibration_constants, ios::beg);
-        calib.read(memblock, size_of_offset_memblock);
-        offset_mV = (float*)memblock;
-        for (int i=0; i<size_of_offset; i++)
-        {
-            // -0.5 is for rounding correctly negative integers.
-            // in all cases where it worked, the offset should be negative for FACT.
-            offset[i] = short(offset_mV / 2000. * 4096 - 0.5);
-        }
-    }
+    calib->SetPtrAddress("BaselineMean",offset_mV, size_of_offset);
+
+    calib->GetNextRow();
+    for (int i =0 ; i<size_of_offset; i++)
+    {
+        offset[i] = short(offset_mV[i] / 2000. * 4096 - 0.5);
+    }
+    cout << endl;
     delete[] offset_mV;
-    delete[] memblock;
-    calib.close();
+    delete calib;
+    calib = NULL;
     //=========================================================================
     // END OF                CALIBRATION CONSTANTS
@@ -90,7 +69,7 @@
     
     
-    ifstream data (data_file_name, ios::in|ios::binary);
+    ifstream datafile (data_file_name, ios::in|ios::binary);
     ofstream out (out_file_name, ios::out|ios::binary|ios::trunc);
-    if (data.is_open() && out.is_open())
+    if (datafile.is_open() && out.is_open())
     {
         // create our own header
@@ -101,15 +80,15 @@
         const int ascii_header_size = 0x2d00;
         char * memblock = new char [ascii_header_size];
-        data.read(memblock, ascii_header_size);
+        datafile.read(memblock, ascii_header_size);
         out.write(memblock, ascii_header_size);
         delete[] memblock;
         
         for ( int event_id = 0 ; event_id < 1000; event_id++)
-        //while ( data.good() )
+        //while ( datafile.good() )
         {
             // copy binary header to new file
             const int bin_header_size = 3390;
             char * memblock = new char [bin_header_size];
-            data.read(memblock, bin_header_size);
+            datafile.read(memblock, bin_header_size);
             out.write(memblock, bin_header_size);
             delete[] memblock;
@@ -125,5 +104,5 @@
                 unsigned char * sizes = new unsigned char [diff_size];
                 
-                data.read(memblock, data_size*sizeof(short) );
+                datafile.read(memblock, data_size*sizeof(short) );
                 
                 for ( int i = 0; i<diff_size; i++)
@@ -195,5 +174,5 @@
                         for (int j = 0; j<group_sizes[i]; j++)
                         {
-                            out.write( (short*)&(diffs[diff_index++]), 2);
+                            out.write( (char*)&(diffs[diff_index++]), 2);
                         }
                     }
@@ -208,8 +187,8 @@
         }
         cout << "finished with 1000 events." << endl;
-        long after_address = data.tellg();
-        data.seekg (0, ios::end);
-        long end = data.tellg();
-        data.seekg (after_address, ios::beg);
+        long after_address = datafile.tellg();
+        datafile.seekg (0, ios::end);
+        long end = datafile.tellg();
+        datafile.seekg (after_address, ios::beg);
         
         cout << "between last event and end:" << end - after_address << endl;
@@ -217,5 +196,5 @@
         const int rest_size = end-after_address;
         char * memblock2 = new char [rest_size];
-        data.read(memblock2, rest_size);
+        datafile.read(memblock2, rest_size);
         cout << "first char in memblock: " << int(memblock2[0]) << endl;
         char lastchar = memblock2[0];
@@ -233,5 +212,5 @@
         
         
-        data.close();
+        datafile.close();
         out.close();
   } //end of if file open
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/test.cpp
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/test.cpp	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/test.cpp	(revision 14268)
@@ -0,0 +1,34 @@
+#include <iostream>
+#include <fstream>
+#include <stdio.h>
+
+using namespace std;
+int main()
+{
+  ofstream out ("test.bin", ios::binary);
+
+  short *a = new short[10];
+  char *b = (char*)a;
+  for (int i=0; i<10; i++)
+  {
+      a[i] = -1938+i;
+  }
+  
+  for (int i=0; i<20; i++)
+  {
+    printf("%X ", (unsigned char)b[i]);
+  }
+  printf("\n");
+    for (int i=0; i<20; i++)
+  {
+    printf("%X ", ((unsigned char*)a)[i]);
+  }
+  printf("\n");
+
+  out.write((char*)a, 10*sizeof(short));
+  out.write(b, 10*sizeof(short));
+  out.write(b, 20);
+  
+  out.close();
+  return 0;
+}
Index: /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/test2.cpp
===================================================================
--- /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/test2.cpp	(revision 14268)
+++ /fact/tools/pyscripts/sandbox/dneise/fact_compress/c++/test2.cpp	(revision 14268)
@@ -0,0 +1,22 @@
+#include <iostream>
+#include <fstream>
+#include <stdio.h>
+
+using namespace std;
+int main()
+{
+  ifstream in ("test.bin", ios::binary);
+
+  short *b = new short[10];
+  
+  in.read((char*)b, 20);
+  
+  for (int i=0; i<10; i++)
+  {
+    printf("%X ", (unsigned short)b[i]);
+  }
+    cout << endl;
+
+  in.close();
+  return 0;
+}
