subtract the 1st value of coulume form next values in the coulume

I want to read a text file.

# Before scan of next column:
# X Y t I
0.01 0.00 1.92 330
0.02 0.00 2.92 335
0.03 0.00 3.92 340
0.04 39.99 9.92 345
# Before scan of next column:
# X Y t I
0.01 0.00 1.92 330
0.02 0.00 2.92 335
0.03 0.00 3.92 330
0.04 39.99 9.92 350
0.05 0.00 3.92 340
0.06 39.99 9.92 345


Want to subtract the 1st value of I form next I values in the coulume.like

# Before scan of next column:
# X Y t I
0.01 0.00 1.92 0
0.02 0.00 2.92 5
0.03 0.00 3.92 10
0.04 39.99 9.92 15
# Before scan of next column:
# X Y t I
0.01 0.00 1.92 0
0.02 0.00 2.92 5
0.03 0.00 3.92 0
0.04 39.99 9.92 20
0.05 0.00 3.92 10
0.06 39.99 9.92 15
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;

int main()
{
// ifstream in( "text.in" );
// ofstream out( "text.out" );
   stringstream in( "# Before scan of next column: \n"
                    "# X Y t I                     \n"
                    "0.01 0.00 1.92 330            \n"
                    "0.02 0.00 2.92 335            \n"
                    "0.03 0.00 3.92 340            \n"
                    "0.04 39.99 9.92 345           \n"
                    "# Before scan of next column: \n"
                    "# X Y t I                     \n"
                    "0.01 0.00 1.92 330            \n"
                    "0.02 0.00 2.92 335            \n"
                    "0.03 0.00 3.92 330            \n"
                    "0.04 39.99 9.92 350           \n"
                    "0.05 0.00 3.92 340            \n"
                    "0.06 39.99 9.92 345           \n" );
   ostream &out = cout;

   bool subtract = false;
   double X, Y, t;
   int I, I0 = 0;
   string line;

   while ( getline( in, line ) )
   {
      if ( line[0] == '#' )
      {
         subtract = false;
         out << line << '\n';
      }
      else
      {
         stringstream( line ) >> X >> Y >> t >> I;
         if ( !subtract ) I0 = I;
         subtract = true;
         I -= I0;
         out << X << " " << Y << " " << t << " " << I << '\n';
      }
   }
}
Last edited on
thanks you so much @lastchance. It works : )
How we can take average of 1st two "I" values and then subtract this average value form form next I values in the column. Thanks
Last edited on
How we can take average of 1st two "I" values and then subtract this average value form form next I values in the column. Thanks
You would have to modify the code to hold up writing the first line of a group until you had the second line and could form an average. (You would also have to decide whether I is an int or a double.) It's messy ... and I can't imagine its purpose.

Why exactly do you want to do this? What is the application?
Hello Prof., @lastchance

Actually, It is the x-ray scanner output. We use X-ray to see the defects of chamber. When x-ray fall on the chamber, we record the current from the chamber.
The 1st few values of current are due to the base/leakage current of the chamber, So we need to subtract the base/leakage current.
With your help I am able to subtract the very 1st value of current(leakage current), but 1st 2 or 3 values form every column are due to base/leakage current, that's why, we have to average and the subtract form proceeding values of current in column. I am a Physics student and have no strong background of programming.

Thanks,
Kind regard,
Khuram
Last edited on
The code below will collect a set of records before outputting them. It has been restructured to facilitate future changes.

You can amend procedure filterRecords() to do any filtering/processing that you like.

At the moment it is set to average the first two elements to get base current, then subtract from the remainder. Amend this as you wish.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

//======================================

struct Record                        
{
   double x;
   double y;
   double t;
   double I;
};

istream &operator >> ( istream &strm, Record &r )
{
   return strm >> r.x >> r.y >> r.t >> r.I;
}

ostream &operator << ( ostream &strm, const Record &r )
{
   return strm << r.x << " " << r.y << " " << r.t << " " << r.I;
}

//======================================

void filterRecords( vector<Record> &R )          // Amend this routine to do whatever filtering you need
{                                                // Currently calculates base current from first NAVERAGE
   const int NAVERAGE = 2;

   if ( R.empty() ) return;          

   // Find average of first NAVERAGE currents (or size of array if smaller)
   int n = NAVERAGE;   if ( n > R.size() ) n = R.size();
   double sum = 0;
   for ( int j = 0; j < n; j++ ) sum += R[j].I;
   double I0 = sum / n;

   // Then subtract this average from all elements
   for ( Record &r : R ) r.I -= I0;
}

//======================================

int main()
{
// ifstream in( "text.in" );
// ofstream out( "text.out" );
   stringstream in( "# Before scan of next column: \n"
                    "# X Y t I                     \n"
                    "0.01 0.00 1.92 330            \n"
                    "0.02 0.00 2.92 335            \n"
                    "0.03 0.00 3.92 340            \n"
                    "0.04 39.99 9.92 345           \n"
                    "# Before scan of next column: \n"
                    "# X Y t I                     \n"
                    "0.01 0.00 1.92 330            \n"
                    "0.02 0.00 2.92 335            \n"
                    "0.03 0.00 3.92 330            \n"
                    "0.04 39.99 9.92 350           \n"
                    "0.05 0.00 3.92 340            \n"
                    "0.06 39.99 9.92 345           \n" );
   ostream &out = cout;

   vector<Record> R;
   string line;

   while ( getline( in, line ) )
   {
      if ( line[0] == '#' )
      {
         // If there is a current array of records, then filter, output and clear
         if ( !R.empty() ) 
         {
            filterRecords( R );
            for ( Record r : R ) out << r << '\n';
            R.clear();
         }
         out << line << '\n';
      }
      else
      {
         // Otherwise, add to current record array
         Record r;
         stringstream( line ) >> r;
         R.push_back( r );
      }
   }

   // At the end, process the last record array
   if ( !R.empty() ) 
   {
      filterRecords( R );
      for ( Record r : R ) out << r << '\n';
      R.clear();
   }
}


# Before scan of next column: 
# X Y t I                     
0.01 0 1.92 -2.5
0.02 0 2.92 2.5
0.03 0 3.92 7.5
0.04 39.99 9.92 12.5
# Before scan of next column: 
# X Y t I                     
0.01 0 1.92 -2.5
0.02 0 2.92 2.5
0.03 0 3.92 -2.5
0.04 39.99 9.92 17.5
0.05 0 3.92 7.5
0.06 39.99 9.92 12.5
@lastchance, thanks a lot for your time and effort.
It helps me very much to focus on the results rather then spending time on the calculations.
Thanks again :)
Topic archived. No new replies allowed.